bfe3675a65ba3397df2d586a9e3d4814beeb54c9
[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
1853         for (c1 = leftovers.page[page].num_pobs - 1; c1 >= 0; c1--)
1854                 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);
1855
1856         leftovers.page[page].num_pobs = 0;
1857
1858 }
1859
1860
1861 char init_level(short level)
1862 {
1863         FILE *handle;
1864         int c1, c2;
1865         int s1, s2;
1866
1867         if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
1868                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1869                 return 1;
1870         }
1871         if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
1872                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
1873                 return 1;
1874         }
1875         fclose(handle);
1876         if ((handle = dat_open("mask.pcx", datfile_name, "rb")) == 0) {
1877                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1878                 return 1;
1879         }
1880         if (read_pcx(handle, mask_pic, 102400L, 0) != 0) {
1881                 strcpy(main_info.error_str, "Error loading 'mask.pcx', aborting...\n");
1882                 return 1;
1883         }
1884         fclose(handle);
1885         memset(cur_pal, 0, 768);
1886
1887         for (c1 = 0; c1 < 4; c1++) {
1888                 if (player[c1].enabled == 1) {
1889                         player[c1].bumps = 0;
1890                         player[c1].bumped[0] = 0;
1891                         player[c1].bumped[1] = 0;
1892                         player[c1].bumped[2] = 0;
1893                         player[c1].bumped[3] = 0;
1894                         position_player(c1);
1895                 }
1896         }
1897
1898         for (c1 = 0; c1 < 300; c1++)
1899                 objects[c1].used = 0;
1900
1901         for (c1 = 0; c1 < 16; c1++) {
1902                 for (c2 = 0; c2 < 22; c2++) {
1903                         if (ban_map[c1][c2] == 4)
1904                                 add_object(OBJ_SPRING, c2 << 4, c1 << 4, 0, 0, OBJ_ANIM_SPRING, 5);
1905                 }
1906         }
1907
1908         while (1) {
1909                 s1 = rnd(22);
1910                 s2 = rnd(16);
1911                 if (ban_map[s2][s1] == 0) {
1912                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1913                         break;
1914                 }
1915         }
1916         while (1) {
1917                 s1 = rnd(22);
1918                 s2 = rnd(16);
1919                 if (ban_map[s2][s1] == 0) {
1920                         add_object(OBJ_YEL_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1921                         break;
1922                 }
1923         }
1924         while (1) {
1925                 s1 = rnd(22);
1926                 s2 = rnd(16);
1927                 if (ban_map[s2][s1] == 0) {
1928                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1929                         break;
1930                 }
1931         }
1932         while (1) {
1933                 s1 = rnd(22);
1934                 s2 = rnd(16);
1935                 if (ban_map[s2][s1] == 0) {
1936                         add_object(OBJ_PINK_BUTFLY, (s1 << 4) + 8, (s2 << 4) + 8, (rnd(65535) - 32768) * 2, (rnd(65535) - 32768) * 2, 0, 0);
1937                         break;
1938                 }
1939         }
1940
1941         return 0;
1942
1943 }
1944
1945
1946 void deinit_level(void)
1947 {
1948         dj_set_nosound(1);
1949         dj_stop_mod();
1950 }
1951
1952
1953 char init_program(int argc, char *argv[])
1954 {
1955         FILE *handle;
1956         int c1, c2;
1957         char load_flag;
1958         char force2, force3;
1959         int player_anim_data[] = {
1960                 1, 0, 0, 0x7fff, 0, 0, 0, 0, 0, 0,
1961                 4, 0, 0, 4, 1, 4, 2, 4, 3, 4,
1962                 1, 0, 4, 0x7fff, 0, 0, 0, 0, 0, 0,
1963                 4, 2, 5, 8, 6, 10, 7, 3, 6, 3,
1964                 1, 0, 6, 0x7fff, 0, 0, 0, 0, 0, 0,
1965                 2, 1, 5, 8, 4, 0x7fff, 0, 0, 0, 0,
1966                 1, 0, 8, 5, 0, 0, 0, 0, 0, 0
1967         };
1968
1969         if (__djgpp_nearptr_enable() == 0)
1970                 return 1;
1971
1972         srandom(time(0));
1973
1974         if (hook_keyb_handler() != 0)
1975                 return 1;
1976
1977         memset(&main_info, 0, sizeof(main_info));
1978         main_info.joy_enabled = 1;
1979
1980         strcpy(datfile_name, "jumpbump.dat");
1981
1982         force2 = force3 = 0;
1983
1984         if (argc > 1) {
1985                 for (c1 = 1; c1 < argc; c1++) {
1986                         if (stricmp(argv[c1], "-nosound") == 0)
1987                                 main_info.no_sound = 1;
1988                         else if (stricmp(argv[c1], "-nogore") == 0)
1989                                 main_info.no_gore = 1;
1990                         else if (stricmp(argv[c1], "-nojoy") == 0)
1991                                 main_info.joy_enabled = 0;
1992                         else if (stricmp(argv[c1], "-fireworks") == 0)
1993                                 main_info.fireworks = 1;
1994                         else if (stricmp(argv[c1], "-dat") == 0) {
1995                                 if (c1 < (argc - 1)) {
1996                                         if ((handle = fopen(argv[c1 + 1], "rb")) != NULL) {
1997                                                 fclose(handle);
1998                                                 strcpy(datfile_name, argv[c1 + 1]);
1999                                         }
2000                                 }
2001                         } else if (stricmp(argv[c1], "-mouse") == 0) {
2002                                 if (c1 < (argc - 1)) {
2003                                         if (stricmp(argv[c1 + 1], "2") == 0)
2004                                                 force2 = 1;
2005                                         if (stricmp(argv[c1 + 1], "3") == 0)
2006                                                 force3 = 1;
2007                                 }
2008                         }
2009                 }
2010         }
2011
2012         for (c1 = 0; c1 < 7; c1++) {
2013                 player_anims[c1].num_frames = player_anim_data[c1 * 10];
2014                 player_anims[c1].restart_frame = player_anim_data[c1 * 10 + 1];
2015                 for (c2 = 0; c2 < 4; c2++) {
2016                         player_anims[c1].frame[c2].image = player_anim_data[c1 * 10 + c2 * 2 + 2];
2017                         player_anims[c1].frame[c2].ticks = player_anim_data[c1 * 10 + c2 * 2 + 3];
2018                 }
2019         }
2020
2021         if ((background_pic = malloc(102400L)) == 0)
2022                 return 1;
2023         if ((mask_pic = malloc(102400L)) == 0)
2024                 return 1;
2025         memset(mask_pic, 0, 102400);
2026
2027         main_info.pob_backbuf[0] = malloc(65535);
2028         main_info.pob_backbuf[1] = malloc(65535);
2029         if (main_info.pob_backbuf[0] == 0 || main_info.pob_backbuf[1] == 0)
2030                 return 1;
2031
2032         if ((handle = dat_open("rabbit.gob", datfile_name, "rb")) == 0) {
2033                 strcpy(main_info.error_str, "Error loading 'rabbit.gob', aborting...\n");
2034                 return 1;
2035         }
2036         if ((rabbit_gobs = malloc(dat_filelen("rabbit.gob", datfile_name))) == 0) {
2037                 strcpy(main_info.error_str, "Not enough memory, aborting...\n");
2038                 fclose(handle);
2039                 return 1;
2040         }
2041         fread(rabbit_gobs, 1, dat_filelen("rabbit.gob", datfile_name), handle);
2042         fclose(handle);
2043
2044         if ((handle = dat_open("objects.gob", datfile_name, "rb")) == 0) {
2045                 strcpy(main_info.error_str, "Error loading 'objects.gob', aborting...\n");
2046                 return 1;
2047         }
2048         if ((object_gobs = malloc(dat_filelen("objects.gob", datfile_name))) == 0) {
2049                 strcpy(main_info.error_str, "Not enough memory, aborting...\n");
2050                 fclose(handle);
2051                 return 1;
2052         }
2053         fread(object_gobs, 1, dat_filelen("objects.gob", datfile_name), handle);
2054         fclose(handle);
2055
2056         if ((handle = dat_open("font.gob", datfile_name, "rb")) == 0) {
2057                 strcpy(main_info.error_str, "Error loading 'font.gob', aborting...\n");
2058                 return 1;
2059         }
2060         if ((font_gobs = malloc(dat_filelen("font.gob", datfile_name))) == 0) {
2061                 strcpy(main_info.error_str, "Not enough memory, aborting...\n");
2062                 fclose(handle);
2063                 return 1;
2064         }
2065         fread(font_gobs, 1, dat_filelen("font.gob", datfile_name), handle);
2066         fclose(handle);
2067
2068         if ((handle = dat_open("numbers.gob", datfile_name, "rb")) == 0) {
2069                 strcpy(main_info.error_str, "Error loading 'numbers.gob', aborting...\n");
2070                 return 1;
2071         }
2072         if ((number_gobs = malloc(dat_filelen("numbers.gob", datfile_name))) == 0) {
2073                 strcpy(main_info.error_str, "Not enough memory, aborting...\n");
2074                 fclose(handle);
2075                 return 1;
2076         }
2077         fread(number_gobs, 1, dat_filelen("numbers.gob", datfile_name), handle);
2078         fclose(handle);
2079
2080         if (read_level() != 0) {
2081                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2082                 fclose(handle);
2083                 return 1;
2084         }
2085
2086         dj_init();
2087         if (main_info.no_sound == 0) {
2088                 dj_autodetect_sd();
2089                 dj_set_mixing_freq(20000);
2090                 dj_set_stereo(0);
2091                 dj_set_auto_mix(0);
2092                 dj_set_dma_time(8);
2093                 dj_set_num_sfx_channels(5);
2094                 dj_set_sfx_volume(64);
2095                 dj_set_nosound(1);
2096                 dj_start();
2097
2098                 if ((handle = dat_open("jump.mod", datfile_name, "rb")) == 0) {
2099                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2100                         return 1;
2101                 }
2102                 if (dj_load_mod(handle, 0, MOD_MENU) != 0) {
2103                         strcpy(main_info.error_str, "Error loading 'jump.mod', aborting...\n");
2104                         return 1;
2105                 }
2106                 fclose(handle);
2107
2108                 if ((handle = dat_open("bump.mod", datfile_name, "rb")) == 0) {
2109                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2110                         return 1;
2111                 }
2112                 if (dj_load_mod(handle, 0, MOD_GAME) != 0) {
2113                         strcpy(main_info.error_str, "Error loading 'bump.mod', aborting...\n");
2114                         return 1;
2115                 }
2116                 fclose(handle);
2117
2118                 if ((handle = dat_open("scores.mod", datfile_name, "rb")) == 0) {
2119                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2120                         return 1;
2121                 }
2122                 if (dj_load_mod(handle, 0, MOD_SCORES) != 0) {
2123                         strcpy(main_info.error_str, "Error loading 'scores.mod', aborting...\n");
2124                         return 1;
2125                 }
2126                 fclose(handle);
2127
2128                 if ((handle = dat_open("jump.smp", datfile_name, "rb")) == 0) {
2129                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2130                         return 1;
2131                 }
2132                 if (dj_load_sfx(handle, 0, dat_filelen("jump.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_JUMP) != 0) {
2133                         strcpy(main_info.error_str, "Error loading 'jump.smp', aborting...\n");
2134                         return 1;
2135                 }
2136                 fclose(handle);
2137
2138                 if ((handle = dat_open("death.smp", datfile_name, "rb")) == 0) {
2139                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2140                         return 1;
2141                 }
2142                 if (dj_load_sfx(handle, 0, dat_filelen("death.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_DEATH) != 0) {
2143                         strcpy(main_info.error_str, "Error loading 'death.smp', aborting...\n");
2144                         return 1;
2145                 }
2146                 fclose(handle);
2147
2148                 if ((handle = dat_open("spring.smp", datfile_name, "rb")) == 0) {
2149                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2150                         return 1;
2151                 }
2152                 if (dj_load_sfx(handle, 0, dat_filelen("spring.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPRING) != 0) {
2153                         strcpy(main_info.error_str, "Error loading 'spring.smp', aborting...\n");
2154                         return 1;
2155                 }
2156                 fclose(handle);
2157
2158                 if ((handle = dat_open("splash.smp", datfile_name, "rb")) == 0) {
2159                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2160                         return 1;
2161                 }
2162                 if (dj_load_sfx(handle, 0, dat_filelen("splash.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_SPLASH) != 0) {
2163                         strcpy(main_info.error_str, "Error loading 'splash.smp', aborting...\n");
2164                         return 1;
2165                 }
2166                 fclose(handle);
2167
2168                 if ((handle = dat_open("fly.smp", datfile_name, "rb")) == 0) {
2169                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2170                         return 1;
2171                 }
2172                 if (dj_load_sfx(handle, 0, dat_filelen("fly.smp", datfile_name), DJ_SFX_TYPE_SMP, SFX_FLY) != 0) {
2173                         strcpy(main_info.error_str, "Error loading 'fly.smp', aborting...\n");
2174                         return 1;
2175                 }
2176                 fclose(handle);
2177
2178                 dj_get_sfx_settings(SFX_FLY, &fly);
2179                 fly.priority = 10;
2180                 fly.default_freq = SFX_FLY_FREQ;
2181                 fly.loop = 1;
2182                 fly.loop_start = 0;
2183                 fly.loop_length = fly.length;
2184                 dj_set_sfx_settings(SFX_FLY, &fly);
2185         }
2186
2187         open_screen();
2188
2189         if ((handle = dat_open("menu.pcx", datfile_name, "rb")) == 0) {
2190                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2191                 return 1;
2192         }
2193         if (read_pcx(handle, background_pic, 102400L, pal) != 0) {
2194                 strcpy(main_info.error_str, "Error loading 'menu.pcx', aborting...\n");
2195                 return 1;
2196         }
2197         fclose(handle);
2198
2199         outportb(0x3c8, 0);
2200         for (c1 = 0; c1 < 768; c1++)
2201                 outportb(0x3c9, pal[c1]);
2202
2203         if (main_info.joy_enabled == 1 && main_info.fireworks == 0) {
2204                 c1 = 0;
2205                 outportb(0x201, 0);
2206                 while (c1 < 0x7fff) {
2207                         if ((inportb(0x201) & 1) == 0)
2208                                 break;
2209                         c1++;
2210                 }
2211                 if (c1 != 0x7fff) {
2212                         main_info.joy_enabled = 1;
2213                         load_flag = 0;
2214                         put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2215                         put_text(0, 200, 100, "Move the joystick to the", 2);
2216                         put_text(0, 200, 115, "UPPER LEFT", 2);
2217                         put_text(0, 200, 130, "and press button A", 2);
2218                         put_text(0, 200, 200, "Or press ESC to use", 2);
2219                         put_text(0, 200, 215, "previous settings", 2);
2220                         if (calib_joy(0) != 0)
2221                                 load_flag = 1;
2222                         else {
2223                                 outportw(0x3c4, 0x0f02);
2224                                 memset((char *) (0xa0000 + 32768 + __djgpp_conventional_base), 0, 32768);
2225                                 main_info.view_page = 1;
2226                                 outportw(0x3d4, (1 << 23) + 0x0d);
2227                                 outportw(0x3d4, ((1 << 15) & 0xff00) + 0x0c);
2228                                 wait_vrt();
2229
2230                                 put_text(1, 200, 40, "JOYSTICK CALIBRATION", 2);
2231                                 put_text(1, 200, 100, "Move the joystick to the", 2);
2232                                 put_text(1, 200, 115, "LOWER RIGHT", 2);
2233                                 put_text(1, 200, 130, "and press button A", 2);
2234                                 put_text(1, 200, 200, "Or press ESC to use", 2);
2235                                 put_text(1, 200, 215, "previous settings", 2);
2236                                 if (calib_joy(1) != 0)
2237                                         load_flag = 1;
2238                                 else {
2239                                         outportw(0x3c4, 0x0f02);
2240                                         memset((char *) (0xa0000 + __djgpp_conventional_base), 0, 32768);
2241                                         outportw(0x3d4, (0 << 23) + 0x0d);
2242                                         outportw(0x3d4, ((0 << 15) & 0xff00) + 0x0c);
2243                                         wait_vrt();
2244
2245                                         put_text(0, 200, 40, "JOYSTICK CALIBRATION", 2);
2246                                         put_text(0, 200, 100, "Move the joystick to the", 2);
2247                                         put_text(0, 200, 115, "CENTER", 2);
2248                                         put_text(0, 200, 130, "and press button A", 2);
2249                                         put_text(0, 200, 200, "Or press ESC to use", 2);
2250                                         put_text(0, 200, 215, "previous settings", 2);
2251                                         if (calib_joy(2) != 0)
2252                                                 load_flag = 1;
2253                                         else {
2254                                                 if (joy.calib_data.x1 == joy.calib_data.x2)
2255                                                         joy.calib_data.x1 -= 10;
2256                                                 if (joy.calib_data.x3 == joy.calib_data.x2)
2257                                                         joy.calib_data.x3 += 10;
2258                                                 if (joy.calib_data.y1 == joy.calib_data.y2)
2259                                                         joy.calib_data.y1 -= 10;
2260                                                 if (joy.calib_data.y3 == joy.calib_data.y2)
2261                                                         joy.calib_data.y3 += 10;
2262                                                 write_calib_data();
2263                                         }
2264                                 }
2265                         }
2266                         if (load_flag == 1) {
2267                                 if ((handle = dat_open("calib.dat", datfile_name, "rb")) == 0) {
2268                                         strcpy(main_info.error_str, "Error loading 'calib.dat', aborting...\n");
2269                                         return 1;
2270                                 }
2271                                 joy.calib_data.x1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2272                                 joy.calib_data.x2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2273                                 joy.calib_data.x3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2274                                 joy.calib_data.y1 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2275                                 joy.calib_data.y2 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2276                                 joy.calib_data.y3 = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2277                                 fclose(handle);
2278                         }
2279                 } else
2280                         main_info.joy_enabled = 0;
2281
2282         }
2283
2284         regs.x.ax = 0;
2285         __dpmi_int(0x33, &regs);
2286         if (regs.x.ax == 0xffff) {
2287                 main_info.mouse_enabled = 1;
2288                 main_info.num_mouse_buttons = regs.x.bx;
2289                 if (force2 == 1)
2290                         main_info.num_mouse_buttons = 2;
2291                 if (force3 == 1)
2292                         main_info.num_mouse_buttons = 3;
2293         } else
2294                 main_info.mouse_enabled = 0;
2295
2296         return 0;
2297
2298 }
2299
2300
2301 void deinit_program(void)
2302 {
2303         __dpmi_regs regs;
2304
2305         dj_stop();
2306         dj_free_mod(MOD_MENU);
2307         dj_free_mod(MOD_GAME);
2308         dj_free_sfx(SFX_DEATH);
2309         dj_free_sfx(SFX_SPRING);
2310         dj_free_sfx(SFX_SPLASH);
2311         dj_deinit();
2312
2313         if (rabbit_gobs != 0)
2314                 free(rabbit_gobs);
2315         if (object_gobs != 0)
2316                 free(object_gobs);
2317         if (number_gobs != 0)
2318                 free(number_gobs);
2319
2320         if (main_info.pob_backbuf[0] != 0)
2321                 free(main_info.pob_backbuf[0]);
2322         if (main_info.pob_backbuf[1] != 0)
2323                 free(main_info.pob_backbuf[1]);
2324
2325         if (background_pic != 0)
2326                 free(background_pic);
2327         if (mask_pic != 0)
2328                 free(mask_pic);
2329
2330         remove_keyb_handler();
2331
2332         regs.x.ax = 0x3;
2333         __dpmi_int(0x10, &regs);
2334
2335         if (main_info.error_str[0] != 0) {
2336                 printf(main_info.error_str);
2337                 exit(1);
2338         } else
2339                 exit(0);
2340
2341 }
2342
2343
2344 void read_joy(void)
2345 {
2346         int c1;
2347         int x, y;
2348         int s1;
2349         char flag;
2350
2351         c1 = x = y = flag = 0;
2352         outportb(0x201, 0);
2353
2354         while (1) {
2355
2356                 s1 = inportb(0x201);
2357
2358                 if (x == 0) {
2359                         if ((s1 & 1) == 0)
2360                                 x = c1;
2361                 }
2362                 if (y == 0) {
2363                         if ((s1 & 2) == 0)
2364                                 y = c1;
2365                 }
2366                 if (x != 0 && y != 0)
2367                         break;
2368
2369                 c1++;
2370                 if (c1 == 0x7fff) {
2371                         flag = 1;
2372                         break;
2373                 }
2374
2375         }
2376
2377         if (flag == 0) {
2378                 joy.raw_x = x;
2379                 joy.raw_y = y;
2380
2381                 if (joy.raw_x < joy.calib_data.x2)
2382                         joy.x = ((long) (joy.raw_x - joy.calib_data.x2) << 10) / (joy.calib_data.x2 - joy.calib_data.x1);
2383                 else
2384                         joy.x = ((long) (joy.raw_x - joy.calib_data.x2) << 10) / (joy.calib_data.x3 - joy.calib_data.x2);
2385                 if (joy.raw_y < joy.calib_data.y2)
2386                         joy.y = ((long) (joy.raw_y - joy.calib_data.y2) << 10) / (joy.calib_data.y2 - joy.calib_data.y1);
2387                 else
2388                         joy.y = ((long) (joy.raw_y - joy.calib_data.y2) << 10) / (joy.calib_data.y3 - joy.calib_data.y2);
2389
2390                 if (joy.x < -1024)
2391                         joy.x = -1024;
2392                 if (joy.x > 1024)
2393                         joy.x = 1024;
2394                 if (joy.y < -1024)
2395                         joy.y = -1024;
2396                 if (joy.y > 1024)
2397                         joy.y = 1024;
2398
2399                 s1 = inportb(0x201);
2400                 joy.but1 = (((s1 >> 4) & 1) ^ 1);
2401                 joy.but2 = (((s1 >> 5) & 1) ^ 1);
2402         } else {
2403                 joy.raw_x = joy.calib_data.x2;
2404                 joy.raw_y = joy.calib_data.y2;
2405
2406                 joy.x = joy.y = 0;
2407
2408                 joy.but1 = joy.but2 = 0;
2409         }
2410
2411 }
2412
2413
2414 char calib_joy(char type)
2415 {
2416         int c1;
2417         int x, y;
2418         int s1;
2419         int num_times;
2420         char flag;
2421
2422         while (joy.but1 == 1) {
2423                 s1 = inportb(0x201);
2424                 joy.but1 = (((s1 >> 4) & 1) ^ 1);
2425                 if (key_pressed(1) == 1) {
2426                         while (key_pressed(1) == 1);
2427                         return 1;
2428                 }
2429         }
2430
2431         num_times = 0;
2432
2433         while (joy.but1 == 0) {
2434
2435                 c1 = x = y = flag = 0;
2436                 outportb(0x201, 0);
2437
2438                 while (1) {
2439
2440                         s1 = inportb(0x201);
2441
2442                         if (x == 0) {
2443                                 if ((s1 & 1) == 0)
2444                                         x = c1;
2445                         }
2446                         if (y == 0) {
2447                                 if ((s1 & 2) == 0)
2448                                         y = c1;
2449                         }
2450                         if (x != 0 && y != 0)
2451                                 break;
2452
2453                         c1++;
2454                         if (c1 == 0x7fff) {
2455                                 flag = 1;
2456                                 break;
2457                         }
2458
2459                 }
2460
2461                 joy.raw_x = x;
2462                 joy.raw_y = y;
2463
2464                 s1 = inportb(0x201);
2465                 joy.but1 = (((s1 >> 4) & 1) ^ 1);
2466
2467                 if (num_times < 0x7fffffff)
2468                         num_times++;
2469
2470                 if (flag == 1)
2471                         break;
2472
2473                 if (key_pressed(1) == 1) {
2474                         while (key_pressed(1) == 1);
2475                         return 1;
2476                 }
2477
2478         }
2479
2480         if (num_times < 16)
2481                 return 1;
2482
2483         if (flag == 0) {
2484
2485                 switch (type) {
2486                 case 0:
2487                         joy.calib_data.x1 = joy.raw_x;
2488                         joy.calib_data.y1 = joy.raw_y;
2489                         break;
2490                 case 1:
2491                         joy.calib_data.x3 = joy.raw_x;
2492                         joy.calib_data.y3 = joy.raw_y;
2493                         break;
2494                 case 2:
2495                         joy.calib_data.x2 = joy.raw_x;
2496                         joy.calib_data.y2 = joy.raw_y;
2497                         break;
2498                 }
2499
2500                 while (joy.but1 == 1) {
2501                         s1 = inportb(0x201);
2502                         joy.but1 = (((s1 >> 4) & 1) ^ 1);
2503                 }
2504
2505         }
2506
2507         return 0;
2508
2509 }
2510
2511
2512 void read_mouse(void)
2513 {
2514
2515         regs.x.ax = 3;
2516         __dpmi_int(0x33, &regs);
2517         mouse.but1 = regs.x.bx & 1;
2518         mouse.but2 = (regs.x.bx & 2) >> 1;
2519         mouse.but3 = (regs.x.bx & 4) >> 2;
2520
2521 }
2522
2523
2524 unsigned short rnd(unsigned short max)
2525 {
2526         return (rand() % max);
2527 }
2528
2529
2530 char read_level(void)
2531 {
2532         FILE *handle;
2533         int c1, c2;
2534         int chr;
2535
2536         if ((handle = dat_open("levelmap.txt", datfile_name, "rb")) == 0) {
2537                 strcpy(main_info.error_str, "Error loading 'levelmap.txt', aborting...\n");
2538                 return 1;
2539         }
2540
2541         for (c1 = 0; c1 < 16; c1++) {
2542                 for (c2 = 0; c2 < 22; c2++) {
2543                         while (1) {
2544                                 chr = fgetc(handle);
2545                                 if (chr == EOF) {
2546                                         fclose(handle);
2547                                         return 1;
2548                                 }
2549                                 if (chr >= '0' && chr <= '4')
2550                                         break;
2551                         }
2552                         ban_map[c1][c2] = chr - '0';
2553                 }
2554         }
2555
2556         for (c2 = 0; c2 < 22; c2++)
2557                 ban_map[16][c2] = 1;
2558
2559         fclose(handle);
2560         return 0;
2561
2562 }
2563
2564
2565 FILE *dat_open(char *file_name, char *dat_name, char *mode)
2566 {
2567         FILE *handle;
2568         int num;
2569         int c1;
2570         char name[21];
2571         int ofs;
2572
2573         if ((handle = fopen(dat_name, mode)) == NULL)
2574                 return 0;
2575
2576         num = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2577         for (c1 = 0; c1 < num; c1++) {
2578                 fread(name, 1, 12, handle);
2579                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2580                         ofs = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2581                         fseek(handle, ofs, SEEK_SET);
2582                         return handle;
2583                 }
2584                 fseek(handle, 8, SEEK_CUR);
2585         }
2586
2587         return 0;
2588 }
2589
2590
2591 int dat_filelen(char *file_name, char *dat_name)
2592 {
2593         FILE *handle;
2594         int num;
2595         int c1;
2596         char name[21];
2597         int len;
2598
2599         if ((handle = fopen(dat_name, "rb")) == NULL)
2600                 return 0;
2601
2602         num = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2603
2604         for (c1 = 0; c1 < num; c1++) {
2605                 fread(name, 1, 12, handle);
2606                 if (strnicmp(name, file_name, strlen(file_name)) == 0) {
2607                         fseek(handle, 4, SEEK_CUR);
2608                         len = fgetc(handle) + (fgetc(handle) << 8) + (fgetc(handle) << 16) + (fgetc(handle) << 24);
2609                         return len;
2610                 }
2611                 fseek(handle, 8, SEEK_CUR);
2612         }
2613
2614         return 0;
2615 }
2616
2617 void write_calib_data(void)
2618 {
2619         FILE *handle;
2620         int c1;
2621         int len, num;
2622         char *mem;
2623         int ofs;
2624
2625         if ((handle = fopen(datfile_name, "rb")) == NULL)
2626                 return;
2627         len = filelength(fileno(handle));
2628         if ((mem = malloc(len)) == NULL)
2629                 return;
2630         fread(mem, 1, len, handle);
2631         fclose(handle);
2632
2633         ofs = 4;
2634         num = *(int *) (&mem[0]);
2635         for (c1 = 0; c1 < num; c1++) {
2636                 if (strnicmp(&mem[ofs], "calib.dat", strlen("calib.dat")) == 0) {
2637                         ofs = *(int *) (&mem[ofs + 12]);
2638                         break;
2639                 }
2640                 ofs += 20;
2641         }
2642
2643         mem[ofs] = joy.calib_data.x1 & 0xff;
2644         mem[ofs + 1] = (joy.calib_data.x1 >> 8) & 0xff;
2645         mem[ofs + 2] = (joy.calib_data.x1 >> 16) & 0xff;
2646         mem[ofs + 3] = (joy.calib_data.x1 >> 24) & 0xff;
2647         mem[ofs + 4] = joy.calib_data.x2 & 0xff;
2648         mem[ofs + 5] = (joy.calib_data.x2 >> 8) & 0xff;
2649         mem[ofs + 6] = (joy.calib_data.x2 >> 16) & 0xff;
2650         mem[ofs + 7] = (joy.calib_data.x2 >> 24) & 0xff;
2651         mem[ofs + 8] = joy.calib_data.x3 & 0xff;
2652         mem[ofs + 9] = (joy.calib_data.x3 >> 8) & 0xff;
2653         mem[ofs + 10] = (joy.calib_data.x3 >> 16) & 0xff;
2654         mem[ofs + 11] = (joy.calib_data.x3 >> 24) & 0xff;
2655         mem[ofs + 12] = joy.calib_data.y1 & 0xff;
2656         mem[ofs + 13] = (joy.calib_data.y1 >> 8) & 0xff;
2657         mem[ofs + 14] = (joy.calib_data.y1 >> 16) & 0xff;
2658         mem[ofs + 15] = (joy.calib_data.y1 >> 24) & 0xff;
2659         mem[ofs + 16] = joy.calib_data.y2 & 0xff;
2660         mem[ofs + 17] = (joy.calib_data.y2 >> 8) & 0xff;
2661         mem[ofs + 18] = (joy.calib_data.y2 >> 16) & 0xff;
2662         mem[ofs + 19] = (joy.calib_data.y2 >> 24) & 0xff;
2663         mem[ofs + 20] = joy.calib_data.y3 & 0xff;
2664         mem[ofs + 21] = (joy.calib_data.y3 >> 8) & 0xff;
2665         mem[ofs + 22] = (joy.calib_data.y3 >> 16) & 0xff;
2666         mem[ofs + 23] = (joy.calib_data.y3 >> 24) & 0xff;
2667
2668         if ((handle = fopen(datfile_name, "wb")) == NULL)
2669                 return;
2670         fwrite(mem, 1, len, handle);
2671         fclose(handle);
2672
2673 }