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