Implemented -scaleup and -nosound options. Some fixes for first release.
[crow/jumpnbump.git] / fireworks.c
1 /*
2  * fireworks.c
3  * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
4  * 
5  * Copyright (C) 2001 tarzeau@space.ch
6  *
7  * Copyright (C) 2002 Florian Schulze - crow@icculus.org
8  *
9  * Portions of this code are from the MPEG software simulation group
10  * idct implementation. This code will be replaced with a new
11  * implementation soon.
12  *
13  * This file is part of Jump'n'Bump.
14  *
15  * Jump'n'Bump is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * Jump'n'Bump is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29
30 #include "globals.h"
31
32 extern unsigned int ban_map[17][22];
33
34 void fireworks(void)
35 {
36         FILE *handle;
37         int c1, c2;
38         int s1, s2, s3;
39         char pal[768];
40         struct {
41                 int used, direction, colour;
42                 int x, y;
43                 int x_add, y_add;
44                 int timer;
45                 int anim, frame, frame_tick, image;
46         } rabbits[20];
47         struct {
48                 int x, y;
49                 int old_x, old_y;
50                 int col;
51                 int back[2];
52         } stars[300];
53
54         register_background(NULL, NULL);
55
56         if ((handle = dat_open("level.pcx", datfile_name, "rb")) == 0) {
57                 strcpy(main_info.error_str, "Error loading 'level.pcx', aborting...\n");
58                 return;
59         }
60         read_pcx(handle, mask_pic, 102400, pal);
61         fclose(handle);
62
63         memset(mask_pic, 0, 102400);
64         register_mask(mask_pic);
65
66         recalculate_gob(&rabbit_gobs, pal);
67         recalculate_gob(&object_gobs, pal);
68
69         memset(ban_map, 0, sizeof(ban_map));
70
71         fillpalette(0, 0, 0);
72
73         draw_begin();
74
75         for (c2 = 193; c2 < 256; c2++) {
76                 clear_lines(0, c2, 1, get_color((c2 - 192) >> 2, pal));
77                 clear_lines(1, c2, 1, get_color((c2 - 192) >> 2, pal));
78         }
79
80         draw_end();
81
82         setpalette(0, 256, pal);
83
84         for (c1 = 0; c1 < 20; c1++)
85                 rabbits[c1].used = 0;
86
87         rabbits[0].used = 1;
88         rabbits[0].colour = rnd(4);
89         rabbits[0].x = (int) (150 + rnd(100)) << 16;
90         rabbits[0].y = 256 << 16;
91         rabbits[0].x_add = ((int) rnd(65535) << 1) - 65536;
92         if (rabbits[0].x_add > 0)
93                 rabbits[0].direction = 0;
94         else
95                 rabbits[0].direction = 1;
96         rabbits[0].y_add = -262144 + (rnd(16384) * 5);
97         rabbits[0].timer = 30 + rnd(150);
98         rabbits[0].anim = 2;
99         rabbits[0].frame = 0;
100         rabbits[0].frame_tick = 0;
101         rabbits[0].image = player_anims[rabbits[0].anim].frame[rabbits[0].frame].image + rabbits[0].colour * 18 + rabbits[0].direction * 9;
102
103         draw_begin();
104         for (c1 = 0; c1 < 300; c1++) {
105                 s1 = rnd(400);
106                 s2 = rnd(256);
107                 s3 = 30 - rnd(7);
108                 stars[c1].x = stars[c1].old_x = (s1 << 16);
109                 stars[c1].y = stars[c1].old_y = (s2 << 16);
110                 stars[c1].col = s3;
111                 stars[c1].back[0] = stars[c1].back[1] = get_pixel(0, s1, s2);
112         }
113         draw_end();
114
115         dj_set_nosound(0);
116
117         main_info.page_info[0].num_pobs = 0;
118         main_info.page_info[1].num_pobs = 0;
119         main_info.view_page = 0;
120         main_info.draw_page = 1;
121
122         while (key_pressed(1) == 0) {
123
124                 dj_mix();
125                 intr_sysupdate();
126
127                 for (c1 = 0; c1 < 300; c1++) {
128                         stars[c1].old_x = stars[c1].x;
129                         stars[c1].old_y = stars[c1].y;
130                         stars[c1].y -= (int) (31 - stars[c1].col) * 16384;
131                         if ((stars[c1].y >> 16) < 0)
132                                 stars[c1].y += JNB_HEIGHT << 16;
133                         if ((stars[c1].y >> 16) >= JNB_HEIGHT)
134                                 stars[c1].y -= JNB_HEIGHT << 16;
135                 }
136
137                 for (c1 = 0, c2 = 0; c1 < 20; c1++) {
138                         if (rabbits[c1].used == 1)
139                                 c2++;
140                 }
141                 if ((c2 == 0 && rnd(10000) < 200) || (c2 == 1 && rnd(10000) < 150) || (c2 == 2 && rnd(10000) < 100) || (c2 == 3 && rnd(10000) < 50)) {
142                         for (c1 = 0; c1 < 20; c1++) {
143                                 if (rabbits[c1].used == 0) {
144                                         rabbits[c1].used = 1;
145                                         rabbits[c1].colour = rnd(4);
146                                         rabbits[c1].x = (int) (150 + rnd(100)) << 16;
147                                         rabbits[c1].y = 256 << 16;
148                                         rabbits[c1].x_add = ((int) rnd(65535) << 1) - 65536;
149                                         if (rabbits[c1].x_add > 0)
150                                                 rabbits[c1].direction = 0;
151                                         else
152                                                 rabbits[c1].direction = 1;
153                                         rabbits[c1].y_add = -262144 + (rnd(16384) * 5);
154                                         rabbits[c1].timer = 30 + rnd(150);
155                                         rabbits[c1].anim = 2;
156                                         rabbits[c1].frame = 0;
157                                         rabbits[c1].frame_tick = 0;
158                                         rabbits[c1].image = player_anims[rabbits[c1].anim].frame[rabbits[c1].frame].image + rabbits[c1].colour * 18 + rabbits[c1].direction * 9;
159                                         break;
160                                 }
161                         }
162                 }
163
164                 dj_mix();
165
166                 main_info.page_info[main_info.draw_page].num_pobs = 0;
167
168                 for (c1 = 0; c1 < 20; c1++) {
169                         if (rabbits[c1].used == 1) {
170                                 rabbits[c1].y_add += 2048;
171                                 if (rabbits[c1].y_add > 36864 && rabbits[c1].anim != 3) {
172                                         rabbits[c1].anim = 3;
173                                         rabbits[c1].frame = 0;
174                                         rabbits[c1].frame_tick = 0;
175                                         rabbits[c1].image = player_anims[rabbits[c1].anim].frame[rabbits[c1].frame].image + rabbits[c1].colour * 18 + rabbits[c1].direction * 9;
176                                 }
177                                 rabbits[c1].x += rabbits[c1].x_add;
178                                 rabbits[c1].y += rabbits[c1].y_add;
179                                 if ((rabbits[c1].x >> 16) < 16 || (rabbits[c1].x >> 16) > 400 || (rabbits[c1].y >> 16) > 256) {
180                                         rabbits[c1].used = 0;
181                                         continue;
182                                 }
183                                 rabbits[c1].timer--;
184                                 if (rabbits[c1].timer <= 0) {
185                                         rabbits[c1].used = 0;
186                                         for (c2 = 0; c2 < 6; c2++)
187                                                 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);
188                                         for (c2 = 0; c2 < 6; c2++)
189                                                 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);
190                                         for (c2 = 0; c2 < 6; c2++)
191                                                 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);
192                                         for (c2 = 0; c2 < 8; c2++)
193                                                 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);
194                                         for (c2 = 0; c2 < 10; c2++)
195                                                 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);
196                                         dj_play_sfx(SFX_DEATH, SFX_DEATH_FREQ, 64, 0, 0, -1);
197                                         continue;
198                                 }
199                                 rabbits[c1].frame_tick++;
200                                 if (rabbits[c1].frame_tick >= player_anims[rabbits[c1].anim].frame[rabbits[c1].frame].ticks) {
201                                         rabbits[c1].frame++;
202                                         if (rabbits[c1].frame >= player_anims[rabbits[c1].anim].num_frames)
203                                                 rabbits[c1].frame = player_anims[rabbits[c1].anim].restart_frame;
204                                         rabbits[c1].frame_tick = 0;
205                                 }
206                                 rabbits[c1].image = player_anims[rabbits[c1].anim].frame[rabbits[c1].frame].image + rabbits[c1].colour * 18 + rabbits[c1].direction * 9;
207                                 if (rabbits[c1].used == 1)
208                                         add_pob(main_info.draw_page, rabbits[c1].x >> 16, rabbits[c1].y >> 16, rabbits[c1].image, &rabbit_gobs);
209                         }
210                 }
211
212                 dj_mix();
213
214                 update_objects();
215
216                 draw_begin();
217
218                 for (c1 = 0; c1 < 300; c1++) {
219                         stars[c1].back[main_info.draw_page] = get_pixel(main_info.draw_page, stars[c1].x >> 16, stars[c1].y >> 16);
220                         set_pixel(main_info.draw_page, stars[c1].x >> 16, stars[c1].y >> 16, get_color(stars[c1].col, pal));
221                 }
222
223                 dj_mix();
224
225                 draw_pobs(main_info.draw_page);
226                 
227                 draw_end();
228
229                 main_info.draw_page ^= 1;
230                 main_info.view_page ^= 1;
231
232                 flippage(main_info.view_page);
233
234                 wait_vrt(1);
235
236                 draw_begin();
237
238                 redraw_pob_backgrounds(main_info.draw_page);
239
240                 dj_mix();
241                 intr_sysupdate();
242
243                 for (c1 = 299; c1 >= 0; c1--) {
244                         set_pixel(main_info.draw_page, stars[c1].old_x >> 16, stars[c1].old_y >> 16, stars[c1].back[main_info.draw_page]);
245                 }
246
247                 draw_end();
248
249         }
250
251         dj_set_nosound(1);
252
253 }
254