2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #define MAX_PARTICLES 2048 // default max # of particles at one
26 #define ABSOLUTE_MIN_PARTICLES 512 // no fewer than this no matter what's
27 // on the command line
29 int ramp1
[8] = {0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61};
30 int ramp2
[8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66};
31 int ramp3
[8] = {0x6d, 0x6b, 6, 5, 4, 3};
33 particle_t
*active_particles
, *free_particles
;
35 particle_t
*particles
;
38 vec3_t r_pright
, r_pup
, r_ppn
;
46 void R_InitParticles (void)
50 i
= COM_CheckParm ("-particles");
54 r_numparticles
= (int)(Q_atoi(com_argv
[i
+1]));
55 if (r_numparticles
< ABSOLUTE_MIN_PARTICLES
)
56 r_numparticles
= ABSOLUTE_MIN_PARTICLES
;
60 r_numparticles
= MAX_PARTICLES
;
63 particles
= (particle_t
*)
64 Hunk_AllocName (r_numparticles
* sizeof(particle_t
), "particles");
68 void R_DarkFieldParticles (entity_t
*ent
)
76 org
[0] = ent
->origin
[0];
77 org
[1] = ent
->origin
[1];
78 org
[2] = ent
->origin
[2];
79 for (i
=-16 ; i
<16 ; i
+=8)
80 for (j
=-16 ; j
<16 ; j
+=8)
81 for (k
=0 ; k
<32 ; k
+=8)
86 free_particles
= p
->next
;
87 p
->next
= active_particles
;
90 p
->die
= cl
.time
+ 0.2 + (rand()&7) * 0.02;
91 p
->color
= 150 + rand()%6;
92 p
->type
= pt_slowgrav
;
98 p
->org
[0] = org
[0] + i
+ (rand()&3);
99 p
->org
[1] = org
[1] + j
+ (rand()&3);
100 p
->org
[2] = org
[2] + k
+ (rand()&3);
102 VectorNormalize (dir
);
103 vel
= 50 + (rand()&63);
104 VectorScale (dir
, vel
, p
->vel
);
116 #define NUMVERTEXNORMALS 162
117 extern float r_avertexnormals
[NUMVERTEXNORMALS
][3];
118 vec3_t avelocities
[NUMVERTEXNORMALS
];
119 float beamlength
= 16;
120 vec3_t avelocity
= {23, 7, 3};
121 float partstep
= 0.01;
122 float timescale
= 0.01;
124 void R_EntityParticles (entity_t
*ent
)
129 float sp
, sy
, cp
, cy
;
135 if (!avelocities
[0][0])
137 for (i
=0 ; i
<NUMVERTEXNORMALS
*3 ; i
++)
138 avelocities
[0][i
] = (rand()&255) * 0.01;
142 for (i
=0 ; i
<NUMVERTEXNORMALS
; i
++)
144 angle
= cl
.time
* avelocities
[i
][0];
147 angle
= cl
.time
* avelocities
[i
][1];
150 angle
= cl
.time
* avelocities
[i
][2];
159 free_particles
= p
->next
;
160 p
->next
= active_particles
;
161 active_particles
= p
;
163 p
->die
= cl
.time
+ 0.01;
165 p
->type
= pt_explode
;
167 p
->org
[0] = ent
->origin
[0] + r_avertexnormals
[i
][0]*dist
+ forward
[0]*beamlength
;
168 p
->org
[1] = ent
->origin
[1] + r_avertexnormals
[i
][1]*dist
+ forward
[1]*beamlength
;
169 p
->org
[2] = ent
->origin
[2] + r_avertexnormals
[i
][2]*dist
+ forward
[2]*beamlength
;
179 void R_ClearParticles (void)
183 free_particles
= &particles
[0];
184 active_particles
= NULL
;
186 for (i
=0 ;i
<r_numparticles
; i
++)
187 particles
[i
].next
= &particles
[i
+1];
188 particles
[r_numparticles
-1].next
= NULL
;
192 void R_ReadPointFile_f (void)
199 char name
[MAX_OSPATH
];
201 sprintf (name
,"maps/%s.pts", sv
.name
);
203 COM_FOpenFile (name
, &f
);
206 Con_Printf ("couldn't open %s\n", name
);
210 Con_Printf ("Reading %s...\n", name
);
214 r
= fscanf (f
,"%f %f %f\n", &org
[0], &org
[1], &org
[2]);
221 Con_Printf ("Not enough free particles\n");
225 free_particles
= p
->next
;
226 p
->next
= active_particles
;
227 active_particles
= p
;
232 VectorCopy (vec3_origin
, p
->vel
);
233 VectorCopy (org
, p
->org
);
237 Con_Printf ("%i points read\n", c
);
242 R_ParseParticleEffect
244 Parse an effect out of the server message
247 void R_ParseParticleEffect (void)
250 int i
, count
, msgcount
, color
;
252 for (i
=0 ; i
<3 ; i
++)
253 org
[i
] = MSG_ReadCoord ();
254 for (i
=0 ; i
<3 ; i
++)
255 dir
[i
] = MSG_ReadChar () * (1.0/16);
256 msgcount
= MSG_ReadByte ();
257 color
= MSG_ReadByte ();
264 R_RunParticleEffect (org
, dir
, color
, count
);
273 void R_ParticleExplosion (vec3_t org
)
278 for (i
=0 ; i
<1024 ; i
++)
283 free_particles
= p
->next
;
284 p
->next
= active_particles
;
285 active_particles
= p
;
287 p
->die
= cl
.time
+ 5;
292 p
->type
= pt_explode
;
293 for (j
=0 ; j
<3 ; j
++)
295 p
->org
[j
] = org
[j
] + ((rand()%32)-16);
296 p
->vel
[j
] = (rand()%512)-256;
301 p
->type
= pt_explode2
;
302 for (j
=0 ; j
<3 ; j
++)
304 p
->org
[j
] = org
[j
] + ((rand()%32)-16);
305 p
->vel
[j
] = (rand()%512)-256;
317 void R_ParticleExplosion2 (vec3_t org
, int colorStart
, int colorLength
)
323 for (i
=0; i
<512; i
++)
328 free_particles
= p
->next
;
329 p
->next
= active_particles
;
330 active_particles
= p
;
332 p
->die
= cl
.time
+ 0.3;
333 p
->color
= colorStart
+ (colorMod
% colorLength
);
337 for (j
=0 ; j
<3 ; j
++)
339 p
->org
[j
] = org
[j
] + ((rand()%32)-16);
340 p
->vel
[j
] = (rand()%512)-256;
351 void R_BlobExplosion (vec3_t org
)
356 for (i
=0 ; i
<1024 ; i
++)
361 free_particles
= p
->next
;
362 p
->next
= active_particles
;
363 active_particles
= p
;
365 p
->die
= cl
.time
+ 1 + (rand()&8)*0.05;
370 p
->color
= 66 + rand()%6;
371 for (j
=0 ; j
<3 ; j
++)
373 p
->org
[j
] = org
[j
] + ((rand()%32)-16);
374 p
->vel
[j
] = (rand()%512)-256;
380 p
->color
= 150 + rand()%6;
381 for (j
=0 ; j
<3 ; j
++)
383 p
->org
[j
] = org
[j
] + ((rand()%32)-16);
384 p
->vel
[j
] = (rand()%512)-256;
396 void R_RunParticleEffect (vec3_t org
, vec3_t dir
, int color
, int count
)
401 for (i
=0 ; i
<count
; i
++)
406 free_particles
= p
->next
;
407 p
->next
= active_particles
;
408 active_particles
= p
;
411 { // rocket explosion
412 p
->die
= cl
.time
+ 5;
417 p
->type
= pt_explode
;
418 for (j
=0 ; j
<3 ; j
++)
420 p
->org
[j
] = org
[j
] + ((rand()%32)-16);
421 p
->vel
[j
] = (rand()%512)-256;
426 p
->type
= pt_explode2
;
427 for (j
=0 ; j
<3 ; j
++)
429 p
->org
[j
] = org
[j
] + ((rand()%32)-16);
430 p
->vel
[j
] = (rand()%512)-256;
436 p
->die
= cl
.time
+ 0.1*(rand()%5);
437 p
->color
= (color
&~7) + (rand()&7);
438 p
->type
= pt_slowgrav
;
439 for (j
=0 ; j
<3 ; j
++)
441 p
->org
[j
] = org
[j
] + ((rand()&15)-8);
442 p
->vel
[j
] = dir
[j
]*15;// + (rand()%300)-150;
455 void R_LavaSplash (vec3_t org
)
462 for (i
=-16 ; i
<16 ; i
++)
463 for (j
=-16 ; j
<16 ; j
++)
464 for (k
=0 ; k
<1 ; k
++)
469 free_particles
= p
->next
;
470 p
->next
= active_particles
;
471 active_particles
= p
;
473 p
->die
= cl
.time
+ 2 + (rand()&31) * 0.02;
474 p
->color
= 224 + (rand()&7);
475 p
->type
= pt_slowgrav
;
477 dir
[0] = j
*8 + (rand()&7);
478 dir
[1] = i
*8 + (rand()&7);
481 p
->org
[0] = org
[0] + dir
[0];
482 p
->org
[1] = org
[1] + dir
[1];
483 p
->org
[2] = org
[2] + (rand()&63);
485 VectorNormalize (dir
);
486 vel
= 50 + (rand()&63);
487 VectorScale (dir
, vel
, p
->vel
);
497 void R_TeleportSplash (vec3_t org
)
504 for (i
=-16 ; i
<16 ; i
+=4)
505 for (j
=-16 ; j
<16 ; j
+=4)
506 for (k
=-24 ; k
<32 ; k
+=4)
511 free_particles
= p
->next
;
512 p
->next
= active_particles
;
513 active_particles
= p
;
515 p
->die
= cl
.time
+ 0.2 + (rand()&7) * 0.02;
516 p
->color
= 7 + (rand()&7);
517 p
->type
= pt_slowgrav
;
523 p
->org
[0] = org
[0] + i
+ (rand()&3);
524 p
->org
[1] = org
[1] + j
+ (rand()&3);
525 p
->org
[2] = org
[2] + k
+ (rand()&3);
527 VectorNormalize (dir
);
528 vel
= 50 + (rand()&63);
529 VectorScale (dir
, vel
, p
->vel
);
533 void R_RocketTrail (vec3_t start
, vec3_t end
, int type
)
540 static int tracercount
;
542 VectorSubtract (end
, start
, vec
);
543 len
= VectorNormalize (vec
);
559 free_particles
= p
->next
;
560 p
->next
= active_particles
;
561 active_particles
= p
;
563 VectorCopy (vec3_origin
, p
->vel
);
564 p
->die
= cl
.time
+ 2;
568 case 0: // rocket trail
569 p
->ramp
= (rand()&3);
570 p
->color
= ramp3
[(int)p
->ramp
];
572 for (j
=0 ; j
<3 ; j
++)
573 p
->org
[j
] = start
[j
] + ((rand()%6)-3);
576 case 1: // smoke smoke
577 p
->ramp
= (rand()&3) + 2;
578 p
->color
= ramp3
[(int)p
->ramp
];
580 for (j
=0 ; j
<3 ; j
++)
581 p
->org
[j
] = start
[j
] + ((rand()%6)-3);
586 p
->color
= 67 + (rand()&3);
587 for (j
=0 ; j
<3 ; j
++)
588 p
->org
[j
] = start
[j
] + ((rand()%6)-3);
593 p
->die
= cl
.time
+ 0.5;
596 p
->color
= 52 + ((tracercount
&4)<<1);
598 p
->color
= 230 + ((tracercount
&4)<<1);
602 VectorCopy (start
, p
->org
);
605 p
->vel
[0] = 30*vec
[1];
606 p
->vel
[1] = 30*-vec
[0];
610 p
->vel
[0] = 30*-vec
[1];
611 p
->vel
[1] = 30*vec
[0];
615 case 4: // slight blood
617 p
->color
= 67 + (rand()&3);
618 for (j
=0 ; j
<3 ; j
++)
619 p
->org
[j
] = start
[j
] + ((rand()%6)-3);
623 case 6: // voor trail
624 p
->color
= 9*16 + 8 + (rand()&3);
626 p
->die
= cl
.time
+ 0.3;
627 for (j
=0 ; j
<3 ; j
++)
628 p
->org
[j
] = start
[j
] + ((rand()&15)-8);
633 VectorAdd (start
, vec
, start
);
643 extern cvar_t sv_gravity
;
645 void R_DrawParticles (void)
647 particle_t
*p
, *kill
;
659 GL_Bind(particletexture
);
661 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
662 glBegin (GL_TRIANGLES
);
664 VectorScale (vup
, 1.5, up
);
665 VectorScale (vright
, 1.5, right
);
669 VectorScale (vright
, xscaleshrink
, r_pright
);
670 VectorScale (vup
, yscaleshrink
, r_pup
);
671 VectorCopy (vpn
, r_ppn
);
673 frametime
= cl
.time
- cl
.oldtime
;
674 time3
= frametime
* 15;
675 time2
= frametime
* 10; // 15;
676 time1
= frametime
* 5;
677 grav
= frametime
* sv_gravity
.value
* 0.05;
682 kill
= active_particles
;
683 if (kill
&& kill
->die
< cl
.time
)
685 active_particles
= kill
->next
;
686 kill
->next
= free_particles
;
687 free_particles
= kill
;
693 for (p
=active_particles
; p
; p
=p
->next
)
698 if (kill
&& kill
->die
< cl
.time
)
700 p
->next
= kill
->next
;
701 kill
->next
= free_particles
;
702 free_particles
= kill
;
709 // hack a scale up to keep particles from disapearing
710 scale
= (p
->org
[0] - r_origin
[0])*vpn
[0] + (p
->org
[1] - r_origin
[1])*vpn
[1]
711 + (p
->org
[2] - r_origin
[2])*vpn
[2];
715 scale
= 1 + scale
* 0.004;
716 glColor3ubv ((byte
*)&d_8to24table
[(int)p
->color
]);
718 glVertex3fv (p
->org
);
720 glVertex3f (p
->org
[0] + up
[0]*scale
, p
->org
[1] + up
[1]*scale
, p
->org
[2] + up
[2]*scale
);
722 glVertex3f (p
->org
[0] + right
[0]*scale
, p
->org
[1] + right
[1]*scale
, p
->org
[2] + right
[2]*scale
);
726 p
->org
[0] += p
->vel
[0]*frametime
;
727 p
->org
[1] += p
->vel
[1]*frametime
;
728 p
->org
[2] += p
->vel
[2]*frametime
;
739 p
->color
= ramp3
[(int)p
->ramp
];
748 p
->color
= ramp1
[(int)p
->ramp
];
749 for (i
=0 ; i
<3 ; i
++)
750 p
->vel
[i
] += p
->vel
[i
]*dvel
;
759 p
->color
= ramp2
[(int)p
->ramp
];
760 for (i
=0 ; i
<3 ; i
++)
761 p
->vel
[i
] -= p
->vel
[i
]*frametime
;
766 for (i
=0 ; i
<3 ; i
++)
767 p
->vel
[i
] += p
->vel
[i
]*dvel
;
772 for (i
=0 ; i
<2 ; i
++)
773 p
->vel
[i
] -= p
->vel
[i
]*dvel
;
779 p
->vel
[2] -= grav
* 20;
790 glDisable (GL_BLEND
);
791 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);