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