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