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