1 /*------------------------------------------------------------------
2 effects.c:
3
4 XINVADERS 3D - 3d Shoot'em up
5 Copyright (C) 2000 Don Llopis
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21 ------------------------------------------------------------------*/
22 #include "game.h"
23
24 /*------------------------------------------------------------------
25 * Stars
26 *
27 *
28 ------------------------------------------------------------------*/
29
30 enum stars_enum
31 {
32 MAX_STARS = 100
33 };
34
35 struct STARSSTRUCT
36 {
37 VECTOR4 pos;
38 VECTOR4 thrustz;
39 int thrust;
40 unsigned int color;
41 } stars[MAX_STARS];
42
43 VECTOR4 star_start = { 0.0f, 0.0f, -2000.0f, 1.0f };
44 VECTOR4 star_thrust[4] = {{ 0.0f, 0.0f, 50.0f, 1.0f },
45 { 0.0f, 0.0f, 25.0f, 1.0f },
46 { 0.0f, 0.0f, 15.0f, 1.0f },
47 { 0.0f, 0.0f, 10.0f, 1.0f } };
48
49
Stars_init(void)50 void Stars_init ( void )
51 {
52 int i, j, k, l, m;
53 for ( i=0; i<MAX_STARS; i++ )
54 {
55 m = rand () % 4;
56 j = rand () % 800;
57 k = rand () % 800;
58 l = rand () % 1000;
59 Vector_copy ( star_start, stars[i].pos );
60
61 stars[i].pos[XPOS] = (float)j;
62 stars[i].pos[YPOS] = (float)k;
63
64 if ( (i % 3) == 0 )
65 {
66 stars[i].pos[XPOS] *= -1.0f;
67 if ( (i%2) == 0 )
68 {
69 stars[i].pos[YPOS] *= -1.0f;
70 }
71 }
72
73 stars[i].thrust = m;
74 stars[i].color = WHITE - (m*15);
75 }
76 }
77
Stars_draw(MATRIX4 r)78 void Stars_draw ( MATRIX4 r )
79 {
80 VECTOR4 tmp;
81 int i, j, m, p[2];
82
83 for ( i=0; i<MAX_STARS; i++ )
84 {
85 j = stars[i].thrust;
86 stars[i].pos[ZPOS] += star_thrust[j][ZPOS] * gv->fadjust;
87
88 if ( stars[i].pos[ZPOS] > -1.0f )
89 {
90 m = rand() % 4;
91 stars[i].thrust = m;
92 stars[i].color = WHITE - (m*15);
93 stars[i].pos[ZPOS] = -2000.0f;
94 }
95 Matrix_vec_mult ( r, stars[i].pos, tmp );
96 Camera_project_point ( tmp, p );
97 Draw_point ( p[0], p[1], stars[i].color );
98 }
99 }
100
101 /*------------------------------------------------------------------
102 * Explosions
103 *
104 *
105 ------------------------------------------------------------------*/
106
107 #define EXPLOSION_ROT 0.23f
108
109 enum explosions_enum
110 {
111 MAX_EXPLOSIONS = 10,
112 MAX_PARTICLES = 4,
113 EXPLOSIONS_LIFE = 1500, /* 1.5 sec */
114 EXPLOSION_BLEND_TIME = 375, /* 0.375 sec */
115 EXPLOSION_COLOR_INC = 15
116 };
117
118 struct EXPLOSIONSTRUCT
119 {
120 VECTOR4 pos[MAX_PARTICLES];
121 int thrust[MAX_PARTICLES];
122 long frame;
123 long blend;
124 int color;
125 int active;
126 } explosions[MAX_EXPLOSIONS];
127
128 static int ecur; /* EXPLOSION index */
129 static int ecount; /* EXPLOSION count */
130 static int pcur; /* THURST index */
131 static float erot; /* EXPLOSIONS rotation */
132
133 /* shard/particle thrust vectors */
134 VECTOR4 pthrust[8] = { {-2.0f, 0.0f, 0.0f, 1.0f},
135 {0.0f, -2.0f, 0.0f, 1.0f},
136 {2.0f, 0.0f, 0.0f, 1.0f},
137 {0.0f, 2.0f, 0.0f, 1.0f},
138 {-2.0f, 2.0f, 0.0f, 1.0f},
139 {2.0f, -2.0f, 0.0f, 1.0f},
140 {-2.0f, -2.0f, 0.0f, 1.0f},
141 {2.0f, 2.0f, 0.0f, 1.0f} };
142
143
144 VECTOR4 shard[3] = { {-5.0f, 0.0f, 0.0f, 1.0f},
145 { 0.0f, 5.0f, 0.0f, 1.0f},
146 { 5.0f, -5.0f, 0.0f, 1.0f}};
147
148
Explosions_clear(void)149 void Explosions_clear ( void )
150 {
151 int i, j;
152
153 ecur = 0;
154 ecount = 0;
155 pcur = 0;
156
157 erot = 0.0f;
158
159 for ( i=0; i<MAX_EXPLOSIONS; i++ )
160 {
161 explosions[i].active = FALSE;
162 explosions[i].frame = 0L;
163 for (j=0; j<MAX_PARTICLES; j++ )
164 Vector_init ( explosions[i].pos[j] );
165 }
166 }
167
Explosions_count(void)168 int Explosions_count ( void )
169 {
170 return ecount;
171 }
172
Explosions_add(OBJECT * obj)173 void Explosions_add ( OBJECT *obj )
174 {
175 explosions[ecur].active = TRUE;
176 explosions[ecur].frame = 0;
177 explosions[ecur].color = GREEN;
178 explosions[ecur].blend = 0;
179
180 /* ok there are currently only 4 */
181 Vector_copy ( obj->pos, explosions[ecur].pos[0] );
182 Vector_copy ( obj->pos, explosions[ecur].pos[1] );
183 Vector_copy ( obj->pos, explosions[ecur].pos[2] );
184 Vector_copy ( obj->pos, explosions[ecur].pos[3] );
185
186 explosions[ecur].thrust[0] = pcur;
187 explosions[ecur].thrust[1] = pcur+1;
188 explosions[ecur].thrust[2] = pcur+2;
189 explosions[ecur].thrust[3] = pcur+3;
190
191 ecur++;
192 pcur += 4;
193 ecount++;
194
195 if ( ecur > MAX_EXPLOSIONS-1 )
196 ecur = 0;
197
198 if ( pcur == 8 )
199 pcur = 0;
200 }
201
Explosions_draw(MATRIX4 r)202 void Explosions_draw ( MATRIX4 r )
203 {
204 int i, j, k, p0[6];
205 VECTOR4 tmp[3], shard_tmp[3];
206 MATRIX4 tmp_mat, tmp_mat2, erot_mat;
207
208 erot += EXPLOSION_ROT * gv->fadjust;
209 Matrix_x_rot ( tmp_mat, erot );
210 Matrix_z_rot ( tmp_mat2, erot );
211 Matrix_mult ( tmp_mat, tmp_mat2, erot_mat );
212 Matrix_vec_multn ( erot_mat, shard, shard_tmp, 3 );
213
214 for ( i=0; i<MAX_EXPLOSIONS; i++ )
215 {
216 if ( explosions[i].active )
217 {
218 explosions[i].frame += gv->msec;
219 if ( explosions[i].frame > EXPLOSIONS_LIFE )
220 {
221 explosions[i].active = FALSE;
222 ecount--;
223 }
224 explosions[i].blend += gv->msec;
225 if ( explosions[i].blend > EXPLOSION_BLEND_TIME )
226 {
227 explosions[i].blend -= EXPLOSION_BLEND_TIME;
228 explosions[i].color -= EXPLOSION_COLOR_INC;
229 }
230
231 for ( j=0; j<MAX_PARTICLES; j++ )
232 {
233 k = explosions[i].thrust[j];
234 explosions[i].pos[j][XPOS] += pthrust[k][XPOS] * gv->fadjust;
235 explosions[i].pos[j][YPOS] += pthrust[k][YPOS] * gv->fadjust;
236 explosions[i].pos[j][ZPOS] += pthrust[k][ZPOS] * gv->fadjust;
237
238 Matrix_vec_mult ( r, explosions[i].pos[j], tmp[0] );
239 Matrix_copy ( r, tmp_mat );
240 Matrix_set_trans ( tmp_mat, tmp[0] );
241
242 Matrix_vec_multn ( tmp_mat, shard_tmp, tmp, 3 );
243 Camera_project_points ( tmp, p0, 3 );
244
245 Draw_line ( p0[0], p0[1], p0[2], p0[3], explosions[i].color );
246 Draw_line ( p0[2], p0[3], p0[4], p0[5], explosions[i].color );
247 Draw_line ( p0[4], p0[5], p0[0], p0[1], explosions[i].color );
248 }
249 }
250 }
251 }
252
253 /*------------------------------------------------------------------
254 * Jump-gate
255 *
256 *
257 ------------------------------------------------------------------*/
258
259 enum jumpgate_enum
260 {
261 MAX_JUMPGATES = 4,
262 JUMPGATE_TIME = 5000,
263 JUMPGATE_ANIM = 250,
264 JUMPGATE_FRAMES = 3
265 };
266
267 struct JUMPGATESTRUCT
268 {
269 int active;
270 long time;
271 long anim;
272 long frame;
273 int dir;
274 VECTOR4 pos;
275 } jgates[MAX_JUMPGATES];
276
277 static int jgcur; /* JUMPGATE index */
278 static int jcount; /* JUMPGATE counter */
279
280 static VECTOR4 jgvert[32] =
281 {
282 {-10.0f, 0.0f, 10.0f, 1.0f},
283 {-0.0f, 10.0f, -10.0f, 1.0f},
284 {10.0f, 0.0f, -10.0f, 1.0f},
285 {0.0f, -10.0f, 10.0f, 1.0f},
286
287 {-30.0f, 0.0f, 30.0f, 1.0f},
288 {0.0f, 30.0f, -30.0f, 1.0f},
289 {30.0f, 0.0f, -30.0f, 1.0f},
290 {0.0f, -30.0f, 30.0f, 1.0f},
291
292 {-50.0f, 0.0f, 50.0f, 1.0f},
293 {0.0f, 50.0f, -50.0f, 1.0f},
294 {50.0f, 0.0f, -50.0f, 1.0f},
295 {0.0f, -50.0f, 50.0f, 1.0f},
296
297 {-70.0f, 0.0f, 70.0f, 1.0f},
298 {0.0f, 70.0f, -70.0f, 1.0f},
299 {70.0f, 0.0f, -70.0f, 1.0f},
300 {0.0f, -70.0f, 70.0f, 1.0f},
301
302 {-10.0f, 0.0f, -10.0f, 1.0f},
303 {0.0f, 10.0f, 10.0f, 1.0f},
304 {10.0f, 0.0f, 10.0f, 1.0f},
305 {0.0f, -10.0f, -10.0f, 1.0f},
306
307 {-30.0f, 0.0f, -30.0f, 1.0f},
308 {0.0f, 30.0f, 30.0f, 1.0f},
309 {30.0f, 0.0f, 30.0f, 1.0f},
310 {0.0f, -30.0f, -30.0f, 1.0f},
311
312 {-50.0f, 0.0f, -50.0f, 1.0f},
313 {0.0f, 50.0f, 50.0f, 1.0f},
314 {50.0f, 0.0f, 50.0f, 1.0f},
315 {0.0f, -50.0f, -50.0f, 1.0f},
316
317 {-70.0f, 0.0f, -70.0f, 1.0f},
318 {0.0f, 70.0f, 70.0f, 1.0f},
319 {70.0f, 0.0f, 70.0f, 1.0f},
320 {0.0f, -70.0f, -70.0f, 1.0f}
321 };
322
Jumpgate_init(void)323 void Jumpgate_init ( void )
324 {
325 int i;
326 for ( i=0; i<MAX_JUMPGATES; i++ )
327 {
328 jgates[i].active = FALSE;
329 jgates[i].time = 0;
330 jgates[i].anim = 0;
331 jgates[i].frame = 0;
332 jgates[i].dir = 0;
333 Vector_init ( jgates[i].pos );
334 }
335 jgcur = 0;
336 jcount = 0;
337 }
338
Jumpgate_open(VECTOR4 pos,int dir)339 void Jumpgate_open ( VECTOR4 pos, int dir )
340 {
341 if ( jcount > MAX_JUMPGATES-1 ) return;
342
343 jgates[jgcur].active = TRUE;
344 jgates[jgcur].time = 0;
345 jgates[jgcur].anim = 0;
346 jgates[jgcur].frame = 0;
347 jgates[jgcur].dir = dir * 16;
348 Vector_copy ( pos, jgates[jgcur].pos );
349
350 jgcur++;
351 if ( jgcur > MAX_JUMPGATES-1 )
352 jgcur = 0;
353
354 jcount++;
355 }
356
Jumpgate_animate(MATRIX4 r)357 void Jumpgate_animate ( MATRIX4 r )
358 {
359 MATRIX4 tmp_mat;
360 VECTOR4 tmp[16];
361 int i, j, p[32], f0;
362
363 for ( i=0; i<MAX_JUMPGATES; i++ )
364 {
365
366 if ( jgates[i].active )
367 {
368 jgates[i].time += gv->msec;
369 jgates[i].anim += gv->msec;
370
371 if ( jgates[i].anim > JUMPGATE_ANIM )
372 {
373 jgates[i].anim -= JUMPGATE_ANIM;
374 jgates[i].frame += 1;
375 if ( jgates[i].frame > JUMPGATE_FRAMES )
376 jgates[i].frame = 0;
377 }
378
379 if ( jgates[i].time > JUMPGATE_TIME )
380 {
381 jgates[i].active = FALSE;
382 jcount--;
383 }
384
385 /* draw jumpgate */
386 Matrix_vec_mult ( r, jgates[i].pos, tmp[0] );
387 Matrix_copy ( r, tmp_mat );
388 Matrix_set_trans ( tmp_mat, tmp[0] );
389
390 f0 = ( jgates[i].frame + 1 ) * 4;
391 Matrix_vec_multn ( tmp_mat,
392 &jgvert[jgates[i].dir], tmp, f0 );
393 Camera_project_points ( tmp, p, f0 );
394 for ( j=0; j<((f0*2)-4); j+=8 )
395 {
396 Draw_line ( p[0+j], p[1+j], p[2+j], p[3+j], GREEN );
397 Draw_line ( p[2+j], p[3+j], p[4+j], p[5+j], GREEN );
398 Draw_line ( p[4+j], p[5+j], p[6+j], p[7+j], GREEN );
399 Draw_line ( p[6+j], p[7+j], p[0+j], p[1+j], GREEN );
400 }
401 }
402 }
403 }
404
405 /*------------------------------------------------------------------
406 * One-up!!!
407 *
408 *
409 ------------------------------------------------------------------*/
410
411 enum oneup_enum
412 {
413 ONEUP_LIFE = 2000,
414 ONEUP_BLEND_TIME = 200
415 };
416
417 struct ONEUPSTRUCT
418 {
419 VECTOR4 pos;
420 long frame;
421 long blend;
422 long color;
423 int active;
424 }one_up;
425
426 static VECTOR4 one_up_vert[10] =
427 {
428 {-40.0f, 20.0f, 0.0f, 1.0f} , /* 1 */
429 {-40.0f, -20.0f, 0.0f, 1.0f },
430 {-20.0f, 20.0f, 0.0f, 1.0f }, /* U */
431 {-20.0f, -20.0f, 0.0f, 1.0f },
432 { 10.0f, -20.0f, 0.0f, 1.0f },
433 { 10.0f, 20.0f, 0.0f, 1.0f },
434 { 20.0f, 20.0f, 0.0f, 1.0f }, /* P */
435 { 20.0f, -20.0f, 0.0f, 1.0f },
436 { 60.0f, 0.0f, 0.0f, 1.0f },
437 { 20.0f, 0.0f, 0.0, 1.0f }
438 };
439
440 static VECTOR4 oneup_thrust = { 0.0f, 0.0f, 10.0f, 1.0f };
441
One_up_init(void)442 void One_up_init ( void )
443 {
444 one_up.active = FALSE;
445 }
446
One_up_add(OBJECT * obj)447 void One_up_add ( OBJECT *obj )
448 {
449 if ( one_up.active == FALSE )
450 {
451 one_up.active = TRUE;
452 Vector_copy ( obj->pos, one_up.pos );
453 one_up.frame = 0;
454 one_up.blend = 0;
455 one_up.color = WHITE;
456 }
457 }
458
One_up_draw(MATRIX4 r)459 void One_up_draw ( MATRIX4 r )
460 {
461 int p0[20];
462 VECTOR4 tmp[10];
463 MATRIX4 tmp_mat;
464
465 if ( one_up.active )
466 {
467 one_up.pos[ZPOS] += oneup_thrust[ZPOS] * gv->fadjust;
468 if ( one_up.pos[ZPOS] > -50.0f )
469 one_up.active = FALSE;
470 one_up.frame += gv->msec;
471 if ( one_up.frame > ONEUP_LIFE )
472 {
473 one_up.active = FALSE;
474 }
475 one_up.blend += gv->msec;
476 if ( one_up.blend > ONEUP_BLEND_TIME )
477 {
478 one_up.blend -= ONEUP_BLEND_TIME;
479 one_up.color -= 3;
480 }
481
482 /* draw one_up */
483 Matrix_vec_mult ( r, one_up.pos, tmp[0] );
484 Matrix_copy ( r, tmp_mat );
485 Matrix_set_trans ( tmp_mat, tmp[0] );
486
487 Matrix_vec_multn ( tmp_mat, one_up_vert, tmp, 10 );
488 Camera_project_points ( tmp, p0, 10 );
489
490 /* draw 1 */
491 Draw_line ( p0[0], p0[1], p0[2], p0[3], one_up.color );
492
493 /* draw U */
494 Draw_line ( p0[4], p0[5], p0[6], p0[7], one_up.color );
495 Draw_line ( p0[6], p0[7], p0[8], p0[9], one_up.color );
496 Draw_line ( p0[8], p0[9], p0[10], p0[11], one_up.color );
497
498 /* draw P */
499 Draw_line ( p0[12], p0[13], p0[14], p0[15], one_up.color );
500 Draw_line ( p0[12], p0[13], p0[16], p0[17], one_up.color );
501 Draw_line ( p0[16], p0[17], p0[18], p0[19], one_up.color );
502 }
503 }
504