Fixes for SDL and VisualC.
[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, 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, 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 = 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, 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 = 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, SFX_JUMP_FREQ + rnd(2000) - 1000, 64, 0, 0, -1);
981                                                         else
982                                                                 dj_play_sfx(SFX_SPRING, 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, SFX_JUMP_FREQ + rnd(2000) - 1000, 64, 0, 0, -1);
995                                                         else
996                                                                 dj_play_sfx(SFX_SPRING, 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, 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, SFX_SPLASH_FREQ + rnd(2000) - 1000, 64, 0, 0, -1);
1134                                                         else
1135                                                                 dj_play_sfx(SFX_SPLASH, 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(short 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 = 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 = 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(char type, short x, short y, long x_add, long y_add, short anim, short 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 = 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 char add_pob(int page, short x, short y, short 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 char add_leftovers(int page, short x, short y, short 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 char init_level(short 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 char 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         open_screen();
2251
2252         if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
2253                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2254                 return 1;
2255         }
2256         if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
2257                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2258                 return 1;
2259         }
2260         fclose(handle);
2261
2262         setpalette(0, 256, pal);
2263
2264         if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2265                 c1 = 0;
2266 #ifdef DOS
2267                 outportb(0x201, 0);
2268                 while (c1 < 0x7fff) {
2269                         if ((inportb(0x201) & 1) == 0)
2270                                 break;
2271                         c1++;
2272                 }
2273 #endif
2274                 if (c1 != 0x7fff) {
2275                         main_info.joy_enabled = 1;
2276                         load_flag = 0;
2277                         put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2278                         put_text(0, 200, 100, "Move the joystick to the", 2);
2279                         put_text(0, 200, 115, "UPPER LEFT", 2);
2280                         put_text(0, 200, 130, "and press button A", 2);
2281                         put_text(0, 200, 200, "Or press ESC to use", 2);
2282                         put_text(0, 200, 215, "previous settings", 2);
2283                         if (calib_joy(0) != 0)
2284                                 load_flag = 1;
2285                         else {
2286 #ifdef DOS
2287                                 outportw(0x3c4, 0x0f02);
2288                                 memset((char *) (0xa0000 + 32768 + __djgpp_conventional_base), 0, 32768);
2289 #else
2290                                 memset((char *) get_vgaptr(1, 0, 0), 0, JNB_WIDTH * JNB_HEIGHT);
2291 #endif
2292
2293                                 main_info.view_page = 1;
2294 #ifdef DOS
2295                                 outportw(0x3d4, (1 << 23) + 0x0d);
2296                                 outportw(0x3d4, ((1 << 15) & 0xff00) + 0x0c);
2297 #else
2298                                 flippage(main_info.view_page);
2299 #endif
2300                                 wait_vrt();
2301
2302                                 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2303                                 put_text(1, 200, 100, "Move the joystick to the", 2);
2304                                 put_text(1, 200, 115, "LOWER RIGHT", 2);
2305                                 put_text(1, 200, 130, "and press button A", 2);
2306                                 put_text(1, 200, 200, "Or press ESC to use", 2);
2307                                 put_text(1, 200, 215, "previous settings", 2);
2308                                 if (calib_joy(1) != 0)
2309                                         load_flag = 1;
2310                                 else {
2311 #ifdef DOS
2312                                         outportw(0x3c4, 0x0f02);
2313                                         memset((char *) (0xa0000 + __djgpp_conventional_base), 0, 32768);
2314                                         outportw(0x3d4, (0 << 23) + 0x0d);
2315                                         outportw(0x3d4, ((0 << 15) & 0xff00) + 0x0c);
2316 #endif
2317                                         wait_vrt();
2318
2319                                         put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2320                                         put_text(0, 200, 100, "Move the joystick to the", 2);
2321                                         put_text(0, 200, 115, "CENTER", 2);
2322                                         put_text(0, 200, 130, "and press button A", 2);
2323                                         put_text(0, 200, 200, "Or press ESC to use", 2);
2324                                         put_text(0, 200, 215, "previous settings", 2);
2325                                         if (calib_joy(2) != 0)
2326                                                 load_flag = 1;
2327                                         else {
2328                                                 if (joy.calib_data.x1 == joy.calib_data.x2)
2329                                                         joy.calib_data.x1 -= 10;
2330                                                 if (joy.calib_data.x3 == joy.calib_data.x2)
2331                                                         joy.calib_data.x3 += 10;
2332                                                 if (joy.calib_data.y1 == joy.calib_data.y2)
2333                                                         joy.calib_data.y1 -= 10;
2334                                                 if (joy.calib_data.y3 == joy.calib_data.y2)
2335                                                         joy.calib_data.y3 += 10;
2336                                                 write_calib_data();
2337                                         }
2338                                 }
2339                         }
2340                         if (load_flag == 1) {
2341                                 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
2342                                         strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2343                                         return 1;
2344                                 }
2345                                 joy.calib_data.x1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2346                                 joy.calib_data.x2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2347                                 joy.calib_data.x3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2348                                 joy.calib_data.y1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2349                                 joy.calib_data.y2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2350                                 joy.calib_data.y3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2351                                 fclose(handle);
2352                         }
2353                 } else
2354                         main_info.joy_enabled = 0;
2355
2356         }
2357 #ifdef DOS
2358         regs.x.ax = 0;
2359         __dpmi_int(0x33, &regs);
2360         if (regs.x.ax == 0xffff) {
2361                 main_info.mouse_enabled = 1;
2362                 main_info.num_mouse_buttons = regs.x.bx;
2363                 if (force2 == 1)
2364                         main_info.num_mouse_buttons = 2;
2365                 if (force3 == 1)
2366                         main_info.num_mouse_buttons = 3;
2367         } else
2368 #endif
2369                 main_info.mouse_enabled = 0;
2370
2371         return 0;
2372
2373 }
2374
2375
2376 void deinit_program(void)
2377 {
2378 #ifdef DOS
2379         __dpmi_regs regs;
2380 #endif
2381
2382         dj_stop();
2383         dj_free_mod(MOD_MENU);
2384         dj_free_mod(MOD_GAME);
2385         dj_free_sfx(SFX_DEATH);
2386         dj_free_sfx(SFX_SPRING);
2387         dj_free_sfx(SFX_SPLASH);
2388         dj_deinit();
2389
2390         if (rabbit_gobs != 0)
2391                 free(rabbit_gobs);
2392         if (object_gobs != 0)
2393                 free(object_gobs);
2394         if (number_gobs != 0)
2395                 free(number_gobs);
2396
2397         if (main_info.pob_backbuf[0] != 0)
2398                 free(main_info.pob_backbuf[0]);
2399         if (main_info.pob_backbuf[1] != 0)
2400                 free(main_info.pob_backbuf[1]);
2401
2402         if (background_pic != 0)
2403                 free(background_pic);
2404         if (mask_pic != 0)
2405                 free(mask_pic);
2406
2407         remove_keyb_handler();
2408
2409 #ifdef DOS
2410         regs.x.ax = 0x3;
2411         __dpmi_int(0x10, &regs);
2412 #endif
2413
2414         if (main_info.error_str[0] != 0) {
2415                 printf(main_info.error_str);
2416                 exit(1);
2417         } else
2418                 exit(0);
2419
2420 }
2421
2422
2423 void read_joy(void)
2424 {
2425         int c1;
2426         int x, y;
2427         int s1 = 0;
2428         char flag;
2429
2430         c1 = x = y = flag = 0;
2431 #ifdef DOS
2432         outportb(0x201, 0);
2433 #endif
2434
2435         while (1) {
2436
2437 #ifdef DOS
2438                 s1 = inportb(0x201);
2439 #endif
2440
2441                 if (x == 0) {
2442                         if ((s1 & 1) == 0)
2443                                 x = c1;
2444                 }
2445                 if (y == 0) {
2446                         if ((s1 & 2) == 0)
2447                                 y = c1;
2448                 }
2449                 if (x != 0 && y != 0)
2450                         break;
2451
2452                 c1++;
2453                 if (c1 == 0x7fff) {
2454                         flag = 1;
2455                         break;
2456                 }
2457
2458         }
2459
2460         if (flag == 0) {
2461                 joy.raw_x = x;
2462                 joy.raw_y = y;
2463
2464                 if (joy.raw_x < joy.calib_data.x2)
2465                         joy.x = ((long) (joy.raw_x - joy.calib_data.x2) << 10) / (joy.calib_data.x2 - joy.calib_data.x1);
2466                 else
2467                         joy.x = ((long) (joy.raw_x - joy.calib_data.x2) << 10) / (joy.calib_data.x3 - joy.calib_data.x2);
2468                 if (joy.raw_y < joy.calib_data.y2)
2469                         joy.y = ((long) (joy.raw_y - joy.calib_data.y2) << 10) / (joy.calib_data.y2 - joy.calib_data.y1);
2470                 else
2471                         joy.y = ((long) (joy.raw_y - joy.calib_data.y2) << 10) / (joy.calib_data.y3 - joy.calib_data.y2);
2472
2473                 if (joy.x < -1024)
2474                         joy.x = -1024;
2475                 if (joy.x > 1024)
2476                         joy.x = 1024;
2477                 if (joy.y < -1024)
2478                         joy.y = -1024;
2479                 if (joy.y > 1024)
2480                         joy.y = 1024;
2481
2482 #ifdef DOS
2483                 s1 = inportb(0x201);
2484 #endif
2485                 joy.but1 = (((s1 >> 4) & 1) ^ 1);
2486                 joy.but2 = (((s1 >> 5) & 1) ^ 1);
2487         } else {
2488                 joy.raw_x = joy.calib_data.x2;
2489                 joy.raw_y = joy.calib_data.y2;
2490
2491                 joy.x = joy.y = 0;
2492
2493                 joy.but1 = joy.but2 = 0;
2494         }
2495
2496 }
2497
2498
2499 char calib_joy(char type)
2500 {
2501         int c1;
2502         int x, y;
2503         int s1 = 0;
2504         int num_times;
2505         char flag = 0;
2506
2507         while (joy.but1 == 1) {
2508 #ifdef DOS
2509                 s1 = inportb(0x201);
2510 #endif
2511                 joy.but1 = (((s1 >> 4) & 1) ^ 1);
2512                 if (key_pressed(1) == 1) {
2513                         while (key_pressed(1) == 1);
2514                         return 1;
2515                 }
2516         }
2517
2518         num_times = 0;
2519
2520         while (joy.but1 == 0) {
2521
2522                 c1 = x = y = flag = 0;
2523 #ifdef DOS
2524                 outportb(0x201, 0);
2525 #endif
2526
2527                 while (1) {
2528
2529 #ifdef DOS
2530                         s1 = inportb(0x201);
2531 #endif
2532
2533                         if (x == 0) {
2534                                 if ((s1 & 1) == 0)
2535                                         x = c1;
2536                         }
2537                         if (y == 0) {
2538                                 if ((s1 & 2) == 0)
2539                                         y = c1;
2540                         }
2541                         if (x != 0 && y != 0)
2542                                 break;
2543
2544                         c1++;
2545                         if (c1 == 0x7fff) {
2546                                 flag = 1;
2547                                 break;
2548                         }
2549
2550                 }
2551
2552                 joy.raw_x = x;
2553                 joy.raw_y = y;
2554
2555 #ifdef DOS
2556                 s1 = inportb(0x201);
2557 #endif
2558                 joy.but1 = (((s1 >> 4) & 1) ^ 1);
2559
2560                 if (num_times < 0x7fffffff)
2561                         num_times++;
2562
2563                 if (flag == 1)
2564                         break;
2565
2566                 if (key_pressed(1) == 1) {
2567                         while (key_pressed(1) == 1);
2568                         return 1;
2569                 }
2570
2571         }
2572
2573         if (num_times < 16)
2574                 return 1;
2575
2576         if (flag == 0) {
2577
2578                 switch (type) {
2579                 case 0:
2580                         joy.calib_data.x1 = joy.raw_x;
2581                         joy.calib_data.y1 = joy.raw_y;
2582                         break;
2583                 case 1:
2584                         joy.calib_data.x3 = joy.raw_x;
2585                         joy.calib_data.y3 = joy.raw_y;
2586                         break;
2587                 case 2:
2588                         joy.calib_data.x2 = joy.raw_x;
2589                         joy.calib_data.y2 = joy.raw_y;
2590                         break;
2591                 }
2592
2593                 while (joy.but1 == 1) {
2594 #ifdef DOS
2595                         s1 = inportb(0x201);
2596 #endif
2597                         joy.but1 = (((s1 >> 4) & 1) ^ 1);
2598                 }
2599
2600         }
2601
2602         return 0;
2603
2604 }
2605
2606
2607 void read_mouse(void)
2608 {
2609
2610 #ifdef DOS
2611         regs.x.ax = 3;
2612         __dpmi_int(0x33, &regs);
2613         mouse.but1 = regs.x.bx & 1;
2614         mouse.but2 = (regs.x.bx & 2) >> 1;
2615         mouse.but3 = (regs.x.bx & 4) >> 2;
2616 #endif
2617
2618 }
2619
2620
2621 unsigned short rnd(unsigned short max)
2622 {
2623         return (rand() % max);
2624 }
2625
2626
2627 char read_level(void)
2628 {
2629         FILE *handle;
2630         int c1, c2;
2631         int chr;
2632
2633         if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
2634                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2635                 return 1;
2636         }
2637
2638         for (c1 = 0; c1 < 16; c1++) {
2639                 for (c2 = 0; c2 < 22; c2++) {
2640                         while (1) {
2641                                 chr = fgetc(handle);
2642                                 if (chr == EOF) {
2643                                         fclose(handle);
2644                                         return 1;
2645                                 }
2646                                 if (chr >= '0' && chr <= '4')
2647                                         break;
2648                         }
2649                         ban_map[c1][c2] = chr - '0';
2650                 }
2651         }
2652
2653         for (c2 = 0; c2 < 22; c2++)
2654                 ban_map[16][c2] = 1;
2655
2656         fclose(handle);
2657         return 0;
2658
2659 }
2660
2661
2662 FILE *dat_open(char *file_name, char *dat_name, char *mode)
2663 {
2664         FILE *handle;
2665         int num;
2666         int c1;
2667         char name[21];
2668         int ofs;
2669
2670         if ((handle = fopen(dat_name, mode)) == NULL)
2671                 return 0;
2672
2673         num = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2674         for (c1 = 0; c1 < num; c1++) {
2675                 fread(name, 1, 12, handle);
2676                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2677                         ofs = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2678                         fseek(handle, ofs, SEEK_SET);
2679                         return handle;
2680                 }
2681                 fseek(handle, 8, SEEK_CUR);
2682         }
2683
2684         return 0;
2685 }
2686
2687
2688 int dat_filelen(char *file_name, char *dat_name)
2689 {
2690         FILE *handle;
2691         int num;
2692         int c1;
2693         char name[21];
2694         int len;
2695
2696         if ((handle = fopen(dat_name, "rb")) == NULL)
2697                 return 0;
2698
2699         num = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2700
2701         for (c1 = 0; c1 < num; c1++) {
2702                 fread(name, 1, 12, handle);
2703                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2704                         fseek(handle, 4, SEEK_CUR);
2705                         len = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2706
2707                         fclose(handle);
2708                         return len;
2709                 }
2710                 fseek(handle, 8, SEEK_CUR);
2711         }
2712
2713         fclose(handle);
2714         return 0;
2715 }
2716
2717 void write_calib_data(void)
2718 {
2719         FILE *handle;
2720         int c1;
2721         int len, num;
2722         char *mem;
2723         int ofs;
2724
2725         if ((handle = fopen(datfile_name, "rb")) == NULL)
2726                 return;
2727         len = filelength(fileno(handle));
2728         if ((mem = malloc(len)) == NULL)
2729                 return;
2730         fread(mem, 1, len, handle);
2731         fclose(handle);
2732
2733         ofs = 4;
2734         num = *(int *) (&mem[0]);
2735         for (c1 = 0; c1 < num; c1++) {
2736                 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2737                         ofs = *(int *) (&mem[ofs + 12]);
2738                         break;
2739                 }
2740                 ofs += 20;
2741         }
2742
2743         mem[ofs] = joy.calib_data.x1 & 0xff;
2744         mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2745         mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2746         mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2747         mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2748         mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2749         mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2750         mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2751         mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2752         mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2753         mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2754         mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2755         mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2756         mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2757         mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2758         mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2759         mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2760         mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2761         mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2762         mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2763         mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2764         mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2765         mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2766         mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2767
2768         if ((handle = fopen(datfile_name, "wb")) == NULL)
2769                 return;
2770         fwrite(mem, 1, len, handle);
2771         fclose(handle);
2772
2773 }