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