Renamed JB_VERSION to JNB_VERSION (GS).
[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                 memset(cur_pal, 0, 768);
791
792                 setpalette(0, 256, cur_pal);
793
794                 mod_vol = 0;
795                 dj_ready_mod(MOD_SCORES);
796                 dj_set_mod_volume((char)mod_vol);
797                 dj_start_mod();
798                 dj_set_nosound(0);
799
800                 while (key_pressed(1) == 0) {
801                         if (mod_vol < 35)
802                                 mod_vol++;
803                         dj_set_mod_volume((char)mod_vol);
804                         for (c1 = 0; c1 < 768; c1++) {
805                                 if (cur_pal[c1] < pal[c1])
806                                         cur_pal[c1]++;
807                         }
808                         dj_mix();
809                         intr_sysupdate();
810                         wait_vrt(0);
811                         setpalette(0, 256, cur_pal);
812                         flippage(main_info.view_page);
813                 }
814                 while (key_pressed(1) == 1) {
815                         dj_mix();
816                         intr_sysupdate();
817                 }
818
819                 memset(pal, 0, 768);
820
821                 while (mod_vol > 0) {
822                         mod_vol--;
823                         dj_set_mod_volume((char)mod_vol);
824                         for (c1 = 0; c1 < 768; c1++) {
825                                 if (cur_pal[c1] > pal[c1])
826                                         cur_pal[c1]--;
827                         }
828                         dj_mix();
829                         wait_vrt(0);
830                         setpalette(0, 256, cur_pal);
831                         flippage(main_info.view_page);
832                 }
833
834                 fillpalette(0, 0, 0);
835
836                 dj_set_nosound(1);
837                 dj_stop_mod();
838
839         }
840
841         deinit_program();
842
843         return 0;
844 }
845
846
847 void steer_players(void)
848 {
849         int c1, c2;
850         int s1 = 0, s2 = 0;
851
852         update_player_actions();
853
854         for (c1 = 0; c1 < 4; c1++) {
855
856                 if (player[c1].enabled == 1) {
857
858                         if (player[c1].dead_flag == 0) {
859
860                                 if (player[c1].action_left && player[c1].action_right) {
861                                         if (player[c1].direction == 0) {
862                                                 if (player[c1].action_right) {
863                                                         s1 = (player[c1].x >> 16);
864                                                         s2 = (player[c1].y >> 16);
865                                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
866                                                                 if (player[c1].x_add < 0)
867                                                                         player[c1].x_add += 1024;
868                                                                 else
869                                                                         player[c1].x_add += 768;
870                                                         } 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)) {
871                                                                 if (player[c1].x_add > 0)
872                                                                         player[c1].x_add += 1024;
873                                                                 else
874                                                                         player[c1].x_add += 768;
875                                                         } else {
876                                                                 if (player[c1].x_add < 0) {
877                                                                         player[c1].x_add += 16384;
878                                                                         if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
879                                                                                 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);
880                                                                 } else
881                                                                         player[c1].x_add += 12288;
882                                                         }
883                                                         if (player[c1].x_add > 98304L)
884                                                                 player[c1].x_add = 98304L;
885                                                         player[c1].direction = 0;
886                                                         if (player[c1].anim == 0) {
887                                                                 player[c1].anim = 1;
888                                                                 player[c1].frame = 0;
889                                                                 player[c1].frame_tick = 0;
890                                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
891                                                         }
892                                                 }
893                                         } else {
894                                                 if (player[c1].action_left) {
895                                                         s1 = (player[c1].x >> 16);
896                                                         s2 = (player[c1].y >> 16);
897                                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
898                                                                 if (player[c1].x_add > 0)
899                                                                         player[c1].x_add -= 1024;
900                                                                 else
901                                                                         player[c1].x_add -= 768;
902                                                         } 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)) {
903                                                                 if (player[c1].x_add > 0)
904                                                                         player[c1].x_add -= 1024;
905                                                                 else
906                                                                         player[c1].x_add -= 768;
907                                                         } else {
908                                                                 if (player[c1].x_add > 0) {
909                                                                         player[c1].x_add -= 16384;
910                                                                         if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
911                                                                                 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);
912                                                                 } else
913                                                                         player[c1].x_add -= 12288;
914                                                         }
915                                                         if (player[c1].x_add < -98304L)
916                                                                 player[c1].x_add = -98304L;
917                                                         player[c1].direction = 1;
918                                                         if (player[c1].anim == 0) {
919                                                                 player[c1].anim = 1;
920                                                                 player[c1].frame = 0;
921                                                                 player[c1].frame_tick = 0;
922                                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
923                                                         }
924                                                 }
925                                         }
926                                 } else if (player[c1].action_left) {
927                                         s1 = (player[c1].x >> 16);
928                                         s2 = (player[c1].y >> 16);
929                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
930                                                 if (player[c1].x_add > 0)
931                                                         player[c1].x_add -= 1024;
932                                                 else
933                                                         player[c1].x_add -= 768;
934                                         } 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)) {
935                                                 if (player[c1].x_add > 0)
936                                                         player[c1].x_add -= 1024;
937                                                 else
938                                                         player[c1].x_add -= 768;
939                                         } else {
940                                                 if (player[c1].x_add > 0) {
941                                                         player[c1].x_add -= 16384;
942                                                         if (player[c1].x_add > -98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
943                                                                 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);
944                                                 } else
945                                                         player[c1].x_add -= 12288;
946                                         }
947                                         if (player[c1].x_add < -98304L)
948                                                 player[c1].x_add = -98304L;
949                                         player[c1].direction = 1;
950                                         if (player[c1].anim == 0) {
951                                                 player[c1].anim = 1;
952                                                 player[c1].frame = 0;
953                                                 player[c1].frame_tick = 0;
954                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
955                                         }
956                                 } else if (player[c1].action_right) {
957                                         s1 = (player[c1].x >> 16);
958                                         s2 = (player[c1].y >> 16);
959                                         if (ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_ICE) {
960                                                 if (player[c1].x_add < 0)
961                                                         player[c1].x_add += 1024;
962                                                 else
963                                                         player[c1].x_add += 768;
964                                         } 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)) {
965                                                 if (player[c1].x_add > 0)
966                                                         player[c1].x_add += 1024;
967                                                 else
968                                                         player[c1].x_add += 768;
969                                         } else {
970                                                 if (player[c1].x_add < 0) {
971                                                         player[c1].x_add += 16384;
972                                                         if (player[c1].x_add < 98304L && player[c1].in_water == 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
973                                                                 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);
974                                                 } else
975                                                         player[c1].x_add += 12288;
976                                         }
977                                         if (player[c1].x_add > 98304L)
978                                                 player[c1].x_add = 98304L;
979                                         player[c1].direction = 0;
980                                         if (player[c1].anim == 0) {
981                                                 player[c1].anim = 1;
982                                                 player[c1].frame = 0;
983                                                 player[c1].frame_tick = 0;
984                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
985                                         }
986                                 } else if ((!player[c1].action_left) && (!player[c1].action_right)) {
987                                         s1 = (player[c1].x >> 16);
988                                         s2 = (player[c1].y >> 16);
989                                         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)))) {
990                                                 if (player[c1].x_add < 0) {
991                                                         player[c1].x_add += 16384;
992                                                         if (player[c1].x_add > 0)
993                                                                 player[c1].x_add = 0;
994                                                 } else {
995                                                         player[c1].x_add -= 16384;
996                                                         if (player[c1].x_add < 0)
997                                                                 player[c1].x_add = 0;
998                                                 }
999                                                 if (player[c1].x_add != 0 && ban_map[(s2 + 16) >> 4][(s1 + 8) >> 4] == BAN_SOLID)
1000                                                         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);
1001                                         }
1002                                         if (player[c1].anim == 1) {
1003                                                 player[c1].anim = 0;
1004                                                 player[c1].frame = 0;
1005                                                 player[c1].frame_tick = 0;
1006                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1007                                         }
1008                                 }
1009                                 if (jetpack == 0) {
1010                                         if (pogostick == 1 || (player[c1].jump_ready == 1 && player[c1].action_up)) {
1011                                                 s1 = (player[c1].x >> 16);
1012                                                 s2 = (player[c1].y >> 16);
1013                                                 if (s2 < -16)
1014                                                         s2 = -16;
1015                                                 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) {
1016                                                         player[c1].y_add = -280000L;
1017                                                         player[c1].anim = 2;
1018                                                         player[c1].frame = 0;
1019                                                         player[c1].frame_tick = 0;
1020                                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1021                                                         player[c1].jump_ready = 0;
1022                                                         player[c1].jump_abort = 1;
1023                                                         if (pogostick == 0)
1024                                                                 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1025                                                         else
1026                                                                 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1027                                                 }
1028                                                 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)) {
1029                                                         player[c1].y_add = -196608L;
1030                                                         player[c1].in_water = 0;
1031                                                         player[c1].anim = 2;
1032                                                         player[c1].frame = 0;
1033                                                         player[c1].frame_tick = 0;
1034                                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1035                                                         player[c1].jump_ready = 0;
1036                                                         player[c1].jump_abort = 1;
1037                                                         if (pogostick == 0)
1038                                                                 dj_play_sfx(SFX_JUMP, (unsigned short)(SFX_JUMP_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1039                                                         else
1040                                                                 dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1041                                                 }
1042                                         }
1043                                         if (pogostick == 0 && (!player[c1].action_up)) {
1044                                                 player[c1].jump_ready = 1;
1045                                                 if (player[c1].in_water == 0 && player[c1].y_add < 0 && player[c1].jump_abort == 1) {
1046                                                         if (bunnies_in_space == 0)
1047                                                                 player[c1].y_add += 32768;
1048                                                         else
1049                                                                 player[c1].y_add += 16384;
1050                                                         if (player[c1].y_add > 0)
1051                                                                 player[c1].y_add = 0;
1052                                                 }
1053                                         }
1054                                 } else {
1055
1056                                         if (player[c1].action_up) {
1057                                                 player[c1].y_add -= 16384;
1058                                                 if (player[c1].y_add < -400000L)
1059                                                         player[c1].y_add = -400000L;
1060                                                 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))
1061                                                         player[c1].in_water = 0;
1062                                                 if (rnd(100) < 50)
1063                                                         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);
1064                                         }
1065
1066                                 }
1067
1068                                 player[c1].x += player[c1].x_add;
1069                                 if ((player[c1].x >> 16) < 0) {
1070                                         player[c1].x = 0;
1071                                         player[c1].x_add = 0;
1072                                 }
1073                                 if ((player[c1].x >> 16) + 15 > 351) {
1074                                         player[c1].x = 336L << 16;
1075                                         player[c1].x_add = 0;
1076                                 }
1077                                 if (player[c1].y > 0) {
1078                                         s1 = (player[c1].x >> 16);
1079                                         s2 = (player[c1].y >> 16);
1080                                         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) {
1081                                                 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1082                                                 player[c1].x_add = 0;
1083                                         }
1084                                         s1 = (player[c1].x >> 16);
1085                                         s2 = (player[c1].y >> 16);
1086                                         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) {
1087                                                 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1088                                                 player[c1].x_add = 0;
1089                                         }
1090                                 } else {
1091                                         s1 = (player[c1].x >> 16);
1092                                         s2 = 0;
1093                                         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) {
1094                                                 player[c1].x = (((s1 + 16) & 0xfff0)) << 16;
1095                                                 player[c1].x_add = 0;
1096                                         }
1097                                         s1 = (player[c1].x >> 16);
1098                                         s2 = 0;
1099                                         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) {
1100                                                 player[c1].x = (((s1 + 16) & 0xfff0) - 16) << 16;
1101                                                 player[c1].x_add = 0;
1102                                         }
1103                                 }
1104
1105                                 player[c1].y += player[c1].y_add;
1106
1107                                 s1 = (player[c1].x >> 16);
1108                                 s2 = (player[c1].y >> 16);
1109                                 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))) {
1110                                         player[c1].y = ((player[c1].y >> 16) & 0xfff0) << 16;
1111                                         player[c1].y_add = -400000L;
1112                                         player[c1].anim = 2;
1113                                         player[c1].frame = 0;
1114                                         player[c1].frame_tick = 0;
1115                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1116                                         player[c1].jump_ready = 0;
1117                                         player[c1].jump_abort = 0;
1118                                         for (c2 = 0; c2 < NUM_OBJECTS; c2++) {
1119                                                 if (objects[c2].used == 1 && objects[c2].type == OBJ_SPRING) {
1120                                                         if (ban_map[(s2 + 15) >> 4][(s1 + 8) >> 4] == BAN_SPRING) {
1121                                                                 if ((objects[c2].x >> 20) == ((s1 + 8) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1122                                                                         objects[c2].frame = 0;
1123                                                                         objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1124                                                                         objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1125                                                                         break;
1126                                                                 }
1127                                                         } else {
1128                                                                 if (ban_map[(s2 + 15) >> 4][s1 >> 4] == BAN_SPRING) {
1129                                                                         if ((objects[c2].x >> 20) == (s1 >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1130                                                                                 objects[c2].frame = 0;
1131                                                                                 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1132                                                                                 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1133                                                                                 break;
1134                                                                         }
1135                                                                 } else if (ban_map[(s2 + 15) >> 4][(s1 + 15) >> 4] == BAN_SPRING) {
1136                                                                         if ((objects[c2].x >> 20) == ((s1 + 15) >> 4) && (objects[c2].y >> 20) == ((s2 + 15) >> 4)) {
1137                                                                                 objects[c2].frame = 0;
1138                                                                                 objects[c2].ticks = object_anims[objects[c2].anim].frame[objects[c2].frame].ticks;
1139                                                                                 objects[c2].image = object_anims[objects[c2].anim].frame[objects[c2].frame].image;
1140                                                                                 break;
1141                                                                         }
1142                                                                 }
1143                                                         }
1144                                                 }
1145                                         }
1146                                         dj_play_sfx(SFX_SPRING, (unsigned short)(SFX_SPRING_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1147                                 }
1148                                 s1 = (player[c1].x >> 16);
1149                                 s2 = (player[c1].y >> 16);
1150                                 if (s2 < 0)
1151                                         s2 = 0;
1152                                 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) {
1153                                         player[c1].y = (((s2 + 16) & 0xfff0)) << 16;
1154                                         player[c1].y_add = 0;
1155                                         player[c1].anim = 0;
1156                                         player[c1].frame = 0;
1157                                         player[c1].frame_tick = 0;
1158                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1159                                 }
1160                                 s1 = (player[c1].x >> 16);
1161                                 s2 = (player[c1].y >> 16);
1162                                 if (s2 < 0)
1163                                         s2 = 0;
1164                                 if (ban_map[(s2 + 8) >> 4][(s1 + 8) >> 4] == BAN_WATER) {
1165                                         if (player[c1].in_water == 0) {
1166                                                 player[c1].in_water = 1;
1167                                                 player[c1].anim = 4;
1168                                                 player[c1].frame = 0;
1169                                                 player[c1].frame_tick = 0;
1170                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1171                                                 if (player[c1].y_add >= 32768) {
1172                                                         add_object(OBJ_SPLASH, (player[c1].x >> 16) + 8, ((player[c1].y >> 16) & 0xfff0) + 15, 0, 0, OBJ_ANIM_SPLASH, 0);
1173                                                         if (blood_is_thicker_than_water == 0)
1174                                                                 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 1000), 64, 0, 0, -1);
1175                                                         else
1176                                                                 dj_play_sfx(SFX_SPLASH, (unsigned short)(SFX_SPLASH_FREQ + rnd(2000) - 5000), 64, 0, 0, -1);
1177                                                 }
1178                                         }
1179                                         player[c1].y_add -= 1536;
1180                                         if (player[c1].y_add < 0 && player[c1].anim != 5) {
1181                                                 player[c1].anim = 5;
1182                                                 player[c1].frame = 0;
1183                                                 player[c1].frame_tick = 0;
1184                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1185                                         }
1186                                         if (player[c1].y_add < -65536L)
1187                                                 player[c1].y_add = -65536L;
1188                                         if (player[c1].y_add > 65535L)
1189                                                 player[c1].y_add = 65535L;
1190                                         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) {
1191                                                 player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1192                                                 player[c1].y_add = 0;
1193                                         }
1194                                 } 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) {
1195                                         player[c1].in_water = 0;
1196                                         player[c1].y = (((s2 + 16) & 0xfff0) - 16) << 16;
1197                                         player[c1].y_add = 0;
1198                                         if (player[c1].anim != 0 && player[c1].anim != 1) {
1199                                                 player[c1].anim = 0;
1200                                                 player[c1].frame = 0;
1201                                                 player[c1].frame_tick = 0;
1202                                                 player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1203                                         }
1204                                 } else {
1205                                         if (player[c1].in_water == 0) {
1206                                                 if (bunnies_in_space == 0)
1207                                                         player[c1].y_add += 12288;
1208                                                 else
1209                                                         player[c1].y_add += 6144;
1210                                                 if (player[c1].y_add > 327680L)
1211                                                         player[c1].y_add = 327680L;
1212                                         } else {
1213                                                 player[c1].y = (player[c1].y & 0xffff0000) + 0x10000;
1214                                                 player[c1].y_add = 0;
1215                                         }
1216                                         player[c1].in_water = 0;
1217                                 }
1218                                 if (player[c1].y_add > 36864 && player[c1].anim != 3 && player[c1].in_water == 0) {
1219                                         player[c1].anim = 3;
1220                                         player[c1].frame = 0;
1221                                         player[c1].frame_tick = 0;
1222                                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1223                                 }
1224
1225                         }
1226
1227                         player[c1].frame_tick++;
1228                         if (player[c1].frame_tick >= player_anims[player[c1].anim].frame[player[c1].frame].ticks) {
1229                                 player[c1].frame++;
1230                                 if (player[c1].frame >= player_anims[player[c1].anim].num_frames) {
1231                                         if (player[c1].anim != 6)
1232                                                 player[c1].frame = player_anims[player[c1].anim].restart_frame;
1233                                         else
1234                                                 position_player(c1);
1235                                 }
1236                                 player[c1].frame_tick = 0;
1237                         }
1238                         player[c1].image = player_anims[player[c1].anim].frame[player[c1].frame].image + player[c1].direction * 9;
1239
1240                 }
1241
1242         }
1243
1244 }
1245
1246
1247 void position_player(int player_num)
1248 {
1249         int c1;
1250         int s1, s2;
1251
1252         while (1) {
1253                 while (1) {
1254                         s1 = rnd(22);
1255                         s2 = rnd(16);
1256                         if (ban_map[s2][s1] == BAN_VOID && (ban_map[s2 + 1][s1] == BAN_SOLID || ban_map[s2 + 1][s1] == BAN_ICE))
1257                                 break;
1258                 }
1259                 for (c1 = 0; c1 < 4; c1++) {
1260                         if (c1 != player_num && player[c1].enabled == 1) {
1261                                 if (abs((s1 << 4) - (player[c1].x >> 16)) < 32 && abs((s2 << 4) - (player[c1].y >> 16)) < 32)
1262                                         break;
1263                         }
1264                 }
1265                 if (c1 == 4) {
1266                         player[player_num].dead_flag = 0;
1267                         player[player_num].x = (long) s1 << 20;
1268                         player[player_num].y = (long) s2 << 20;
1269                         player[player_num].x_add = player[player_num].y_add = 0;
1270                         player[player_num].direction = 0;
1271                         player[player_num].jump_ready = 1;
1272                         player[player_num].in_water = 0;
1273                         player[player_num].anim = 0;
1274                         player[player_num].frame = 0;
1275                         player[player_num].frame_tick = 0;
1276                         player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
1277                         break;
1278                 }
1279         }
1280
1281 }
1282
1283
1284 void add_object(int type, int x, int y, int x_add, int y_add, int anim, int frame)
1285 {
1286         int c1;
1287
1288         for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1289                 if (objects[c1].used == 0) {
1290                         objects[c1].used = 1;
1291                         objects[c1].type = type;
1292                         objects[c1].x = (long) x << 16;
1293                         objects[c1].y = (long) y << 16;
1294                         objects[c1].x_add = x_add;
1295                         objects[c1].y_add = y_add;
1296                         objects[c1].x_acc = 0;
1297                         objects[c1].y_acc = 0;
1298                         objects[c1].anim = anim;
1299                         objects[c1].frame = frame;
1300                         objects[c1].ticks = object_anims[anim].frame[frame].ticks;
1301                         objects[c1].image = object_anims[anim].frame[frame].image;
1302                         break;
1303                 }
1304         }
1305
1306 }
1307
1308
1309 void update_objects(void)
1310 {
1311         int c1;
1312         int s1 = 0;
1313
1314         for (c1 = 0; c1 < NUM_OBJECTS; c1++) {
1315                 if (objects[c1].used == 1) {
1316                         switch (objects[c1].type) {
1317                         case OBJ_SPRING:
1318                                 objects[c1].ticks--;
1319                                 if (objects[c1].ticks <= 0) {
1320                                         objects[c1].frame++;
1321                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames) {
1322                                                 objects[c1].frame--;
1323                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1324                                         } else {
1325                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1326                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1327                                         }
1328                                 }
1329                                 if (objects[c1].used == 1)
1330                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1331                                 break;
1332                         case OBJ_SPLASH:
1333                                 objects[c1].ticks--;
1334                                 if (objects[c1].ticks <= 0) {
1335                                         objects[c1].frame++;
1336                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1337                                                 objects[c1].used = 0;
1338                                         else {
1339                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1340                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1341                                         }
1342                                 }
1343                                 if (objects[c1].used == 1)
1344                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1345                                 break;
1346                         case OBJ_SMOKE:
1347                                 objects[c1].x += objects[c1].x_add;
1348                                 objects[c1].y += objects[c1].y_add;
1349                                 objects[c1].ticks--;
1350                                 if (objects[c1].ticks <= 0) {
1351                                         objects[c1].frame++;
1352                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1353                                                 objects[c1].used = 0;
1354                                         else {
1355                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1356                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1357                                         }
1358                                 }
1359                                 if (objects[c1].used == 1)
1360                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1361                                 break;
1362                         case OBJ_YEL_BUTFLY:
1363                         case OBJ_PINK_BUTFLY:
1364                                 objects[c1].x_acc += rnd(128) - 64;
1365                                 if (objects[c1].x_acc < -1024)
1366                                         objects[c1].x_acc = -1024;
1367                                 if (objects[c1].x_acc > 1024)
1368                                         objects[c1].x_acc = 1024;
1369                                 objects[c1].x_add += objects[c1].x_acc;
1370                                 if (objects[c1].x_add < -32768)
1371                                         objects[c1].x_add = -32768;
1372                                 if (objects[c1].x_add > 32768)
1373                                         objects[c1].x_add = 32768;
1374                                 objects[c1].x += objects[c1].x_add;
1375                                 if ((objects[c1].x >> 16) < 16) {
1376                                         objects[c1].x = 16 << 16;
1377                                         objects[c1].x_add = -objects[c1].x_add >> 2;
1378                                         objects[c1].x_acc = 0;
1379                                 } else if ((objects[c1].x >> 16) > 350) {
1380                                         objects[c1].x = 350 << 16;
1381                                         objects[c1].x_add = -objects[c1].x_add >> 2;
1382                                         objects[c1].x_acc = 0;
1383                                 }
1384                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1385                                         if (objects[c1].x_add < 0) {
1386                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1387                                         } else {
1388                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1389                                         }
1390                                         objects[c1].x_add = -objects[c1].x_add >> 2;
1391                                         objects[c1].x_acc = 0;
1392                                 }
1393                                 objects[c1].y_acc += rnd(64) - 32;
1394                                 if (objects[c1].y_acc < -1024)
1395                                         objects[c1].y_acc = -1024;
1396                                 if (objects[c1].y_acc > 1024)
1397                                         objects[c1].y_acc = 1024;
1398                                 objects[c1].y_add += objects[c1].y_acc;
1399                                 if (objects[c1].y_add < -32768)
1400                                         objects[c1].y_add = -32768;
1401                                 if (objects[c1].y_add > 32768)
1402                                         objects[c1].y_add = 32768;
1403                                 objects[c1].y += objects[c1].y_add;
1404                                 if ((objects[c1].y >> 16) < 0) {
1405                                         objects[c1].y = 0;
1406                                         objects[c1].y_add = -objects[c1].y_add >> 2;
1407                                         objects[c1].y_acc = 0;
1408                                 } else if ((objects[c1].y >> 16) > 255) {
1409                                         objects[c1].y = 255 << 16;
1410                                         objects[c1].y_add = -objects[c1].y_add >> 2;
1411                                         objects[c1].y_acc = 0;
1412                                 }
1413                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0) {
1414                                         if (objects[c1].y_add < 0) {
1415                                                 objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1416                                         } else {
1417                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1418                                         }
1419                                         objects[c1].y_add = -objects[c1].y_add >> 2;
1420                                         objects[c1].y_acc = 0;
1421                                 }
1422                                 if (objects[c1].type == OBJ_YEL_BUTFLY) {
1423                                         if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_LEFT) {
1424                                                 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_LEFT;
1425                                                 objects[c1].frame = 0;
1426                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1427                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1428                                         } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_YEL_BUTFLY_RIGHT) {
1429                                                 objects[c1].anim = OBJ_ANIM_YEL_BUTFLY_RIGHT;
1430                                                 objects[c1].frame = 0;
1431                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1432                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1433                                         }
1434                                 } else {
1435                                         if (objects[c1].x_add < 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_LEFT) {
1436                                                 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_LEFT;
1437                                                 objects[c1].frame = 0;
1438                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1439                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1440                                         } else if (objects[c1].x_add > 0 && objects[c1].anim != OBJ_ANIM_PINK_BUTFLY_RIGHT) {
1441                                                 objects[c1].anim = OBJ_ANIM_PINK_BUTFLY_RIGHT;
1442                                                 objects[c1].frame = 0;
1443                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1444                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1445                                         }
1446                                 }
1447                                 objects[c1].ticks--;
1448                                 if (objects[c1].ticks <= 0) {
1449                                         objects[c1].frame++;
1450                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1451                                                 objects[c1].frame = object_anims[objects[c1].anim].restart_frame;
1452                                         else {
1453                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1454                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1455                                         }
1456                                 }
1457                                 if (objects[c1].used == 1)
1458                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1459                                 break;
1460                         case OBJ_FUR:
1461                                 if (rnd(100) < 30)
1462                                         add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 0);
1463                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1464                                         objects[c1].y_add += 3072;
1465                                         if (objects[c1].y_add > 196608L)
1466                                                 objects[c1].y_add = 196608L;
1467                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1468                                         if (objects[c1].x_add < 0) {
1469                                                 if (objects[c1].x_add < -65536L)
1470                                                         objects[c1].x_add = -65536L;
1471                                                 objects[c1].x_add += 1024;
1472                                                 if (objects[c1].x_add > 0)
1473                                                         objects[c1].x_add = 0;
1474                                         } else {
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                                         }
1481                                         objects[c1].y_add += 1024;
1482                                         if (objects[c1].y_add < -65536L)
1483                                                 objects[c1].y_add = -65536L;
1484                                         if (objects[c1].y_add > 65536L)
1485                                                 objects[c1].y_add = 65536L;
1486                                 }
1487                                 objects[c1].x += objects[c1].x_add;
1488                                 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)) {
1489                                         if (objects[c1].x_add < 0) {
1490                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1491                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
1492                                         } else {
1493                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1494                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
1495                                         }
1496                                 }
1497                                 objects[c1].y += objects[c1].y_add;
1498                                 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1499                                         objects[c1].used = 0;
1500                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1501                                         if (objects[c1].y_add < 0) {
1502                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1503                                                         objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1504                                                         objects[c1].x_add >>= 2;
1505                                                         objects[c1].y_add = -objects[c1].y_add >> 2;
1506                                                 }
1507                                         } else {
1508                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1509                                                         if (objects[c1].y_add > 131072L) {
1510                                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1511                                                                 objects[c1].x_add >>= 2;
1512                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
1513                                                         } else
1514                                                                 objects[c1].used = 0;
1515                                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1516                                                         objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1517                                                         if (objects[c1].y_add > 131072L)
1518                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
1519                                                         else
1520                                                                 objects[c1].y_add = 0;
1521                                                 }
1522                                         }
1523                                 }
1524                                 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1525                                         objects[c1].x_add = -16384;
1526                                 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1527                                         objects[c1].x_add = 16384;
1528                                 if (objects[c1].used == 1) {
1529                                         s1 = (int)(atan2(objects[c1].y_add, objects[c1].x_add) * 4 / M_PI);
1530                                         if (s1 < 0)
1531                                                 s1 += 8;
1532                                         if (s1 < 0)
1533                                                 s1 = 0;
1534                                         if (s1 > 7)
1535                                                 s1 = 7;
1536                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame + s1, &object_gobs);
1537                                 }
1538                                 break;
1539                         case OBJ_FLESH:
1540                                 if (rnd(100) < 30) {
1541                                         if (objects[c1].frame == 76)
1542                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 1);
1543                                         else if (objects[c1].frame == 77)
1544                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 2);
1545                                         else if (objects[c1].frame == 78)
1546                                                 add_object(OBJ_FLESH_TRACE, objects[c1].x >> 16, objects[c1].y >> 16, 0, 0, OBJ_ANIM_FLESH_TRACE, 3);
1547                                 }
1548                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 0) {
1549                                         objects[c1].y_add += 3072;
1550                                         if (objects[c1].y_add > 196608L)
1551                                                 objects[c1].y_add = 196608L;
1552                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 2) {
1553                                         if (objects[c1].x_add < 0) {
1554                                                 if (objects[c1].x_add < -65536L)
1555                                                         objects[c1].x_add = -65536L;
1556                                                 objects[c1].x_add += 1024;
1557                                                 if (objects[c1].x_add > 0)
1558                                                         objects[c1].x_add = 0;
1559                                         } else {
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                                         }
1566                                         objects[c1].y_add += 1024;
1567                                         if (objects[c1].y_add < -65536L)
1568                                                 objects[c1].y_add = -65536L;
1569                                         if (objects[c1].y_add > 65536L)
1570                                                 objects[c1].y_add = 65536L;
1571                                 }
1572                                 objects[c1].x += objects[c1].x_add;
1573                                 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)) {
1574                                         if (objects[c1].x_add < 0) {
1575                                                 objects[c1].x = (((objects[c1].x >> 16) + 16) & 0xfff0) << 16;
1576                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
1577                                         } else {
1578                                                 objects[c1].x = ((((objects[c1].x >> 16) - 16) & 0xfff0) + 15) << 16;
1579                                                 objects[c1].x_add = -objects[c1].x_add >> 2;
1580                                         }
1581                                 }
1582                                 objects[c1].y += objects[c1].y_add;
1583                                 if ((objects[c1].x >> 16) < -5 || (objects[c1].x >> 16) > 405 || (objects[c1].y >> 16) > 260)
1584                                         objects[c1].used = 0;
1585                                 if ((objects[c1].y >> 16) > 0 && (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 0)) {
1586                                         if (objects[c1].y_add < 0) {
1587                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] != 2) {
1588                                                         objects[c1].y = (((objects[c1].y >> 16) + 16) & 0xfff0) << 16;
1589                                                         objects[c1].x_add >>= 2;
1590                                                         objects[c1].y_add = -objects[c1].y_add >> 2;
1591                                                 }
1592                                         } else {
1593                                                 if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 1) {
1594                                                         if (objects[c1].y_add > 131072L) {
1595                                                                 objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1596                                                                 objects[c1].x_add >>= 2;
1597                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
1598                                                         } else {
1599                                                                 if (rnd(100) < 10) {
1600                                                                         s1 = rnd(4) - 2;
1601                                                                         add_leftovers(0, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1602                                                                         add_leftovers(1, objects[c1].x >> 16, (objects[c1].y >> 16) + s1, objects[c1].frame, &object_gobs);
1603                                                                 }
1604                                                                 objects[c1].used = 0;
1605                                                         }
1606                                                 } else if (ban_map[objects[c1].y >> 20][objects[c1].x >> 20] == 3) {
1607                                                         objects[c1].y = ((((objects[c1].y >> 16) - 16) & 0xfff0) + 15) << 16;
1608                                                         if (objects[c1].y_add > 131072L)
1609                                                                 objects[c1].y_add = -objects[c1].y_add >> 2;
1610                                                         else
1611                                                                 objects[c1].y_add = 0;
1612                                                 }
1613                                         }
1614                                 }
1615                                 if (objects[c1].x_add < 0 && objects[c1].x_add > -16384)
1616                                         objects[c1].x_add = -16384;
1617                                 if (objects[c1].x_add > 0 && objects[c1].x_add < 16384)
1618                                         objects[c1].x_add = 16384;
1619                                 if (objects[c1].used == 1)
1620                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].frame, &object_gobs);
1621                                 break;
1622                         case OBJ_FLESH_TRACE:
1623                                 objects[c1].ticks--;
1624                                 if (objects[c1].ticks <= 0) {
1625                                         objects[c1].frame++;
1626                                         if (objects[c1].frame >= object_anims[objects[c1].anim].num_frames)
1627                                                 objects[c1].used = 0;
1628                                         else {
1629                                                 objects[c1].ticks = object_anims[objects[c1].anim].frame[objects[c1].frame].ticks;
1630                                                 objects[c1].image = object_anims[objects[c1].anim].frame[objects[c1].frame].image;
1631                                         }
1632                                 }
1633                                 if (objects[c1].used == 1)
1634                                         add_pob(main_info.draw_page, objects[c1].x >> 16, objects[c1].y >> 16, objects[c1].image, &object_gobs);
1635                                 break;
1636                         }
1637                 }
1638         }
1639
1640 }
1641
1642
1643 int add_pob(int page, int x, int y, int image, gob_t *pob_data)
1644 {
1645
1646         if (main_info.page_info[page].num_pobs >= NUM_POBS)
1647                 return 1;
1648
1649         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].x = x;
1650         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].y = y;
1651         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].image = image;
1652         main_info.page_info[page].pobs[main_info.page_info[page].num_pobs].pob_data = pob_data;
1653         main_info.page_info[page].num_pobs++;
1654
1655         return 0;
1656
1657 }
1658
1659
1660 void draw_flies(int page)
1661 {
1662         int c2;
1663
1664         for (c2 = 0; c2 < NUM_FLIES; c2++) {
1665                 flies[c2].back[main_info.draw_page] = get_pixel(main_info.draw_page, flies[c2].x, flies[c2].y);
1666                 flies[c2].back_defined[main_info.draw_page] = 1;
1667                 if (mask_pic[(flies[c2].y * JNB_WIDTH) + flies[c2].x] == 0)
1668                         set_pixel(main_info.draw_page, flies[c2].x, flies[c2].y, 0);
1669         }
1670 }
1671
1672 void draw_pobs(int page)
1673 {
1674         int c1;
1675         int back_buf_ofs;
1676
1677         back_buf_ofs = 0;
1678
1679         for (c1 = main_info.page_info[page].num_pobs - 1; c1 >= 0; c1--) {
1680                 main_info.page_info[page].pobs[c1].back_buf_ofs = back_buf_ofs;
1681                 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);
1682                 if (scale_up)
1683                         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;
1684                 else
1685                         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;
1686                 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);
1687         }
1688
1689 }
1690
1691
1692 void redraw_flies_background(int page)
1693 {
1694         int c2;
1695
1696         for (c2 = NUM_FLIES - 1; c2 >= 0; c2--) {
1697                 if (flies[c2].back_defined[page] == 1)
1698                         set_pixel(page, flies[c2].old_draw_x, flies[c2].old_draw_y, flies[c2].back[page]);
1699                 flies[c2].old_draw_x = flies[c2].x;
1700                 flies[c2].old_draw_y = flies[c2].y;
1701         }
1702 }
1703
1704
1705 void redraw_pob_backgrounds(int page)
1706 {
1707         int c1;
1708
1709         for (c1 = 0; c1 < main_info.page_info[page].num_pobs; c1++)
1710                 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);
1711
1712 }
1713
1714
1715 int add_leftovers(int page, int x, int y, int image, gob_t *pob_data)
1716 {
1717
1718         if (leftovers.page[page].num_pobs >= NUM_LEFTOVERS)
1719                 return 1;
1720
1721         leftovers.page[page].pobs[leftovers.page[page].num_pobs].x = x;
1722         leftovers.page[page].pobs[leftovers.page[page].num_pobs].y = y;
1723         leftovers.page[page].pobs[leftovers.page[page].num_pobs].image = image;
1724         leftovers.page[page].pobs[leftovers.page[page].num_pobs].pob_data = pob_data;
1725         leftovers.page[page].num_pobs++;
1726
1727         return 0;
1728
1729 }
1730
1731
1732 void draw_leftovers(int page)
1733 {
1734         int c1;
1735
1736         for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
1737                 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);
1738
1739         leftovers.page[page].num_pobs = 0;
1740
1741 }
1742
1743
1744 int init_level(int level, char *pal)
1745 {
1746         FILE *handle;
1747         int c1, c2;
1748         int s1, s2;
1749
1750         if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
1751                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1752                 return 1;
1753         }
1754         if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1755                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1756                 return 1;
1757         }
1758         fclose(handle);
1759         if (flip)
1760                 flip_pixels(background_pic);
1761         if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
1762                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1763                 return 1;
1764         }
1765         if (read_pcx(handle, mask_pic, 102400L, 0) != 0) {
1766                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1767                 return 1;
1768         }
1769         fclose(handle);
1770         if (flip)
1771                 flip_pixels(mask_pic);
1772         register_mask(mask_pic);
1773
1774         for (c1 = 0; c1 < 4; c1++) {
1775                 if (player[c1].enabled == 1) {
1776                         player[c1].bumps = 0;
1777                         player[c1].bumped[0] = 0;
1778                         player[c1].bumped[1] = 0;
1779                         player[c1].bumped[2] = 0;
1780                         player[c1].bumped[3] = 0;
1781                         position_player(c1);
1782                 }
1783         }
1784
1785         for (c1 = 0; c1 < NUM_OBJECTS; c1++)
1786                 objects[c1].used = 0;
1787
1788         for (c1 = 0; c1 < 16; c1++) {
1789                 for (c2 = 0; c2 < 22; c2++) {
1790                         if (ban_map[c1][c2] == BAN_SPRING)
1791                                 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
1792                 }
1793         }
1794
1795         while (1) {
1796                 s1 = rnd(22);
1797                 s2 = rnd(16);
1798                 if (ban_map[s2][s1] == BAN_VOID) {
1799                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1800                         break;
1801                 }
1802         }
1803         while (1) {
1804                 s1 = rnd(22);
1805                 s2 = rnd(16);
1806                 if (ban_map[s2][s1] == BAN_VOID) {
1807                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1808                         break;
1809                 }
1810         }
1811         while (1) {
1812                 s1 = rnd(22);
1813                 s2 = rnd(16);
1814                 if (ban_map[s2][s1] == BAN_VOID) {
1815                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1816                         break;
1817                 }
1818         }
1819         while (1) {
1820                 s1 = rnd(22);
1821                 s2 = rnd(16);
1822                 if (ban_map[s2][s1] == BAN_VOID) {
1823                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1824                         break;
1825                 }
1826         }
1827
1828         return 0;
1829
1830 }
1831
1832
1833 void deinit_level(void)
1834 {
1835         dj_set_nosound(1);
1836         dj_stop_mod();
1837 }
1838
1839
1840 int init_program(int argc, char *argv[], char *pal)
1841 {
1842         FILE *handle = (FILE *) NULL;
1843         int c1 = 0, c2 = 0;
1844         int load_flag = 0;
1845         int force2, force3;
1846         sfx_data fly;
1847         int player_anim_data[] = {
1848                 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
1849                 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
1850                 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
1851                 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
1852                 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
1853                 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
1854                 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
1855         };
1856
1857 #ifdef DOS
1858         if (__djgpp_nearptr_enable() == 0)
1859                 return 1;
1860 #endif
1861
1862         srand(time(NULL));
1863
1864         if (hook_keyb_handler() != 0)
1865                 return 1;
1866
1867         memset(&main_info, 0, sizeof(main_info));
1868
1869         strcpy(datfile_name, DATA_PATH);
1870
1871         force2 = force3 = 0;
1872
1873         if (argc > 1) {
1874                 for (c1 = 1; c1 < argc; c1++) {
1875                         if (stricmp(argv[c1], "-nosound") == 0)
1876                                 main_info.no_sound = 1;
1877                         else if (stricmp(argv[c1], "-musicnosound") == 0)
1878                                 main_info.music_no_sound = 1;
1879                         else if (stricmp(argv[c1], "-nogore") == 0)
1880                                 main_info.no_gore = 1;
1881                         else if (stricmp(argv[c1], "-nojoy") == 0)
1882                                 main_info.joy_enabled = 0;
1883                         else if (stricmp(argv[c1], "-fireworks") == 0)
1884                                 main_info.fireworks = 1;
1885 #ifdef USE_SDL
1886                         else if (stricmp(argv[c1], "-fullscreen") == 0)
1887                                 fs_toggle();
1888 #endif
1889                         else if (stricmp(argv[c1], "-scaleup") == 0)
1890                                 set_scaling(1);
1891                         else if (stricmp(argv[c1], "-mirror") == 0)
1892                                 flip = 1;
1893                         else if (stricmp(argv[c1], "-dat") == 0) {
1894                                 if (c1 < (argc - 1)) {
1895                                         if ((handle = fopen(argv[c1 + 1], "rb")) != NULL) {
1896                                                 fclose(handle);
1897                                                 strcpy(datfile_name, argv[c1 + 1]);
1898                                         }
1899                                 }
1900                         } else if (stricmp(argv[c1], "-mouse") == 0) {
1901                                 if (c1 < (argc - 1)) {
1902                                         if (stricmp(argv[c1 + 1], "2") == 0)
1903                                                 force2 = 1;
1904                                         if (stricmp(argv[c1 + 1], "3") == 0)
1905                                                 force3 = 1;
1906                                 }
1907                         }
1908                         else if (strstr(argv[1],"-v")) {
1909                                 printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
1910 #ifndef _SDLnet_h
1911                                 printf("out");
1912 #endif
1913                                 printf(" network support.\n");
1914                                 return 1;
1915                         }
1916                         else if (strstr(argv[1],"-h")) {
1917                                 printf("Usage: jumpnbump [OPTION]...\n");
1918                                 printf("\n");
1919                                 printf("  -h                       this help\n");
1920                                 printf("  -v                       print version\n");
1921                                 printf("  -dat level.dat           play a different level\n");
1922                                 printf("  -port port               define listen port\n");
1923                                 printf("  -net player host rport   define network players\n");
1924                                 printf("  -fireworks               screensaver mode\n");
1925                                 printf("  -fullscreen              run in fullscreen mode\n");
1926                                 printf("  -nosound                 play without sound\n");
1927                                 printf("  -nogore                  play without blood\n");
1928                                 printf("  -mirror                  play with mirrored level\n");
1929                                 printf("  -scaleup                 play with doubled resolution (800x512)\n");
1930                                 printf("\n");
1931                                 return 1;
1932                         }
1933                 }
1934         }
1935
1936         main_info.pob_backbuf[0] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1937         main_info.pob_backbuf[1] = malloc(screen_pitch*screen_height*bytes_per_pixel);
1938
1939         for (c1 = 0; c1 < 7; c1++) {
1940                 player_anims[c1].num_frames = player_anim_data[c1 * 10];
1941                 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
1942                 for (c2 = 0; c2 < 4; c2++) {
1943                         player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
1944                         player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
1945                 }
1946         }
1947
1948         if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
1949                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1950                 return 1;
1951         }
1952         if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1953                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
1954                 return 1;
1955         }
1956         fclose(handle);
1957
1958         if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
1959                 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
1960                 return 1;
1961         }
1962         if (register_gob(handle, &rabbit_gobs, dat_filelen("rabbit.gob", datfile_name))) {
1963                 /* error */
1964                 fclose(handle);
1965                 return 1;
1966         }
1967         fclose(handle);
1968
1969         if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
1970                 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
1971                 return 1;
1972         }
1973         if (register_gob(handle, &object_gobs, dat_filelen("objects.gob", datfile_name))) {
1974                 /* error */
1975                 fclose(handle);
1976                 return 1;
1977         }
1978         fclose(handle);
1979
1980         if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
1981                 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
1982                 return 1;
1983         }
1984         if (register_gob(handle, &font_gobs, dat_filelen("font.gob", datfile_name))) {
1985                 /* error */
1986                 fclose(handle);
1987                 return 1;
1988         }
1989         fclose(handle);
1990
1991         if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
1992                 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
1993                 return 1;
1994         }
1995         if (register_gob(handle, &number_gobs, dat_filelen("numbers.gob", datfile_name))) {
1996                 /* error */
1997                 fclose(handle);
1998                 return 1;
1999         }
2000         fclose(handle);
2001
2002         if (read_level() != 0) {
2003                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2004                 fclose(handle);
2005                 return 1;
2006         }
2007
2008         dj_init();
2009
2010         if (main_info.no_sound == 0) {
2011                 dj_autodetect_sd();
2012                 dj_set_mixing_freq(20000);
2013                 dj_set_stereo(0);
2014                 dj_set_auto_mix(0);
2015                 dj_set_dma_time(8);
2016                 dj_set_num_sfx_channels(5);
2017                 dj_set_sfx_volume(64);
2018                 dj_set_nosound(1);
2019                 dj_start();
2020
2021                 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2022                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2023                         return 1;
2024                 }
2025                 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2026                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2027                         return 1;
2028                 }
2029                 fclose(handle);
2030
2031                 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2032                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2033                         return 1;
2034                 }
2035                 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2036                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2037                         return 1;
2038                 }
2039                 fclose(handle);
2040
2041                 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2042                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2043                         return 1;
2044                 }
2045                 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2046                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2047                         return 1;
2048                 }
2049                 fclose(handle);
2050
2051                 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2052                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2053                         return 1;
2054                 }
2055                 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2056                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2057                         return 1;
2058                 }
2059                 fclose(handle);
2060
2061                 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2062                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2063                         return 1;
2064                 }
2065                 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2066                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2067                         return 1;
2068                 }
2069                 fclose(handle);
2070
2071                 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2072                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2073                         return 1;
2074                 }
2075                 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2076                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2077                         return 1;
2078                 }
2079                 fclose(handle);
2080
2081                 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2082                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2083                         return 1;
2084                 }
2085                 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2086                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2087                         return 1;
2088                 }
2089                 fclose(handle);
2090
2091                 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2092                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2093                         return 1;
2094                 }
2095                 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2096                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2097                         return 1;
2098                 }
2099                 fclose(handle);
2100
2101                 dj_get_sfx_settings(SFX_FLY, &fly);
2102                 fly.priority = 10;
2103                 fly.default_freq = SFX_FLY_FREQ;
2104                 fly.loop = 1;
2105                 fly.loop_start = 0;
2106                 fly.loop_length = fly.length;
2107                 dj_set_sfx_settings(SFX_FLY, &fly);
2108         }
2109
2110         if ((background_pic = malloc(102400)) == NULL)
2111                 return 1;
2112         if ((mask_pic = malloc(102400)) == NULL)
2113                 return 1;
2114         memset(mask_pic, 0, 102400);
2115         register_mask(mask_pic);
2116
2117         setpalette(0, 256, pal);
2118
2119         init_inputs();
2120
2121         recalculate_gob(&font_gobs, pal);
2122
2123         if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2124                 load_flag = 0;
2125                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2126                 put_text(0, 200, 100, "Move the joystick to the", 2);
2127                 put_text(0, 200, 115, "UPPER LEFT", 2);
2128                 put_text(0, 200, 130, "and press button A", 2);
2129                 put_text(0, 200, 200, "Or press ESC to use", 2);
2130                 put_text(0, 200, 215, "previous settings", 2);
2131                 if (calib_joy(0) != 0)
2132                         load_flag = 1;
2133                 else {
2134                         register_background(NULL, NULL);
2135
2136                         main_info.view_page = 1;
2137                         flippage(1);
2138
2139                         wait_vrt(0);
2140
2141                         put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2142                         put_text(1, 200, 100, "Move the joystick to the", 2);
2143                         put_text(1, 200, 115, "LOWER RIGHT", 2);
2144                         put_text(1, 200, 130, "and press button A", 2);
2145                         put_text(1, 200, 200, "Or press ESC to use", 2);
2146                         put_text(1, 200, 215, "previous settings", 2);
2147                         if (calib_joy(1) != 0)
2148                                 load_flag = 1;
2149                         else {
2150                                 register_background(NULL, NULL);
2151                                 flippage(0);
2152
2153                                 wait_vrt(0);
2154
2155                                 put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2156                                 put_text(0, 200, 100, "Move the joystick to the", 2);
2157                                 put_text(0, 200, 115, "CENTER", 2);
2158                                 put_text(0, 200, 130, "and press button A", 2);
2159                                 put_text(0, 200, 200, "Or press ESC to use", 2);
2160                                 put_text(0, 200, 215, "previous settings", 2);
2161                                 if (calib_joy(2) != 0)
2162                                         load_flag = 1;
2163                                 else {
2164                                         if (joy.calib_data.x1 == joy.calib_data.x2)
2165                                                 joy.calib_data.x1 -= 10;
2166                                         if (joy.calib_data.x3 == joy.calib_data.x2)
2167                                                 joy.calib_data.x3 += 10;
2168                                         if (joy.calib_data.y1 == joy.calib_data.y2)
2169                                                 joy.calib_data.y1 -= 10;
2170                                         if (joy.calib_data.y3 == joy.calib_data.y2)
2171                                                 joy.calib_data.y3 += 10;
2172                                         write_calib_data();
2173                                 }
2174                         }
2175                 }
2176                 if (load_flag == 1) {
2177                         if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
2178                                 strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2179                                 return 1;
2180                         }
2181                         joy.calib_data.x1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2182                         joy.calib_data.x2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2183                         joy.calib_data.x3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2184                         joy.calib_data.y1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2185                         joy.calib_data.y2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2186                         joy.calib_data.y3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2187                         fclose(handle);
2188                 }
2189         }
2190
2191         return 0;
2192
2193 }
2194
2195 void deinit_program(void)
2196 {
2197 #ifdef DOS
2198         __dpmi_regs regs;
2199 #endif
2200
2201         dj_stop();
2202         dj_free_mod(MOD_MENU);
2203         dj_free_mod(MOD_GAME);
2204         dj_free_sfx(SFX_DEATH);
2205         dj_free_sfx(SFX_SPRING);
2206         dj_free_sfx(SFX_SPLASH);
2207         dj_deinit();
2208
2209         if (background_pic != 0)
2210                 free(background_pic);
2211         if (mask_pic != 0)
2212                 free(mask_pic);
2213
2214         remove_keyb_handler();
2215
2216 #ifdef DOS
2217         regs.x.ax = 0x3;
2218         __dpmi_int(0x10, &regs);
2219 #endif
2220
2221         if (main_info.error_str[0] != 0) {
2222                 printf(main_info.error_str);
2223 #ifdef _MSC_VER
2224                 MessageBox(0, main_info.error_str, "Jump'n'Bump", 0);
2225 #endif
2226                 exit(1);
2227         } else
2228                 exit(0);
2229
2230 }
2231
2232
2233 unsigned short rnd(unsigned short max)
2234 {
2235         return (rand() % max);
2236 }
2237
2238
2239 int read_level(void)
2240 {
2241         FILE *handle;
2242         int c1, c2;
2243         int chr;
2244
2245         if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
2246                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2247                 return 1;
2248         }
2249
2250         for (c1 = 0; c1 < 16; c1++) {
2251                 for (c2 = 0; c2 < 22; c2++) {
2252                         while (1) {
2253                                 chr = fgetc(handle);
2254                                 if (chr == EOF) {
2255                                         fclose(handle);
2256                                         return 1;
2257                                 }
2258                                 if (chr >= '0' && chr <= '4')
2259                                         break;
2260                         }
2261                         if (flip)
2262                                 ban_map[c1][21-c2] = chr - '0';
2263                         else
2264                                 ban_map[c1][c2] = chr - '0';
2265                 }
2266         }
2267
2268         for (c2 = 0; c2 < 22; c2++)
2269                 ban_map[16][c2] = BAN_SOLID;
2270
2271         fclose(handle);
2272         return 0;
2273
2274 }
2275
2276
2277 FILE *dat_open(char *file_name, char *dat_name, char *mode)
2278 {
2279         FILE *handle;
2280         int num;
2281         int c1;
2282         char name[21];
2283         int ofs;
2284
2285         handle = fopen(dat_name, mode);
2286         if (!handle)
2287                 return 0;
2288
2289         memset(name, 0, sizeof(name));
2290
2291         num = fgetc(handle);
2292         num+= (fgetc(handle) << 8);
2293         num+= (fgetc(handle) << 16);
2294         num+= (fgetc(handle) << 24);
2295         
2296         for (c1 = 0; c1 < num; c1++) {
2297                 if (!fread(name, 1, 12, handle)) {
2298                         fclose(handle);
2299                         return 0;
2300                 }
2301                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2302                         ofs = fgetc(handle);
2303                         ofs += (fgetc(handle) << 8);
2304                         ofs += (fgetc(handle) << 16);
2305                         ofs += (fgetc(handle) << 24);
2306                         fseek(handle, ofs, SEEK_SET);
2307                         return handle;
2308                 }
2309                 fseek(handle, 8, SEEK_CUR);
2310         }
2311
2312         fclose(handle);
2313
2314         return 0;
2315 }
2316
2317
2318 int dat_filelen(char *file_name, char *dat_name)
2319 {
2320         FILE *handle;
2321         int num;
2322         int c1;
2323         char name[21];
2324         int len;
2325
2326         handle = fopen(dat_name, "rb");
2327         if (!handle)
2328                 return 0;
2329
2330         memset(name, 0, sizeof(name));
2331         
2332         num = fgetc(handle);
2333         num+= (fgetc(handle) << 8);
2334         num+= (fgetc(handle) << 16);
2335         num+= (fgetc(handle) << 24);
2336
2337         for (c1 = 0; c1 < num; c1++) {
2338                 if (!fread(name, 1, 12, handle)) {
2339                         fclose(handle);
2340                         return 0;
2341                 }
2342                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2343                         fseek(handle, 4, SEEK_CUR);
2344                         len = fgetc(handle);
2345                         len += (fgetc(handle) << 8);
2346                         len += (fgetc(handle) << 16);
2347                         len += (fgetc(handle) << 24);
2348
2349                         fclose(handle);
2350                         return len;
2351                 }
2352                 fseek(handle, 8, SEEK_CUR);
2353         }
2354
2355         fclose(handle);
2356         return 0;
2357 }
2358
2359
2360 #ifndef _MSC_VER
2361 int filelength(int handle)
2362 {
2363         struct stat buf;
2364
2365         if (fstat(handle, &buf) == -1) {
2366                 perror("filelength");
2367                 exit(EXIT_FAILURE);
2368         }
2369
2370         return buf.st_size;
2371 }
2372 #endif
2373
2374
2375 void write_calib_data(void)
2376 {
2377         FILE *handle;
2378         int c1;
2379         int len, num;
2380         char *mem;
2381         int ofs;
2382
2383         if ((handle = fopen(datfile_name, "rb")) == NULL)
2384                 return;
2385         len = filelength(fileno(handle));
2386         if ((mem = malloc(len)) == NULL)
2387                 return;
2388         fread(mem, 1, len, handle);
2389         fclose(handle);
2390
2391         ofs = 4;
2392         num = *(int *) (&mem[0]);
2393         for (c1 = 0; c1 < num; c1++) {
2394                 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2395                         ofs = *(int *) (&mem[ofs + 12]);
2396                         break;
2397                 }
2398                 ofs += 20;
2399         }
2400
2401         mem[ofs] = joy.calib_data.x1 & 0xff;
2402         mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2403         mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2404         mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2405         mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2406         mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2407         mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2408         mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2409         mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2410         mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2411         mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2412         mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2413         mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2414         mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2415         mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2416         mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2417         mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2418         mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2419         mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2420         mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2421         mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2422         mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2423         mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2424         mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2425
2426         if ((handle = fopen(datfile_name, "wb")) == NULL)
2427                 return;
2428         fwrite(mem, 1, len, handle);
2429         fclose(handle);
2430
2431 }