Fix for the problem that SDL applications exited
[AROS-Contrib.git] / Games / Quake / r_part.c
blobb7dfe0dac6445a46f65845e729b9272808171f9a
1 /*
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.
21 #include "quakedef.h"
22 #include "r_local.h"
24 #define MAX_PARTICLES 2048 // default max # of particles at one
25 // time
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;
36 int r_numparticles;
38 vec3_t r_pright, r_pup, r_ppn;
42 ===============
43 R_InitParticles
44 ===============
46 void R_InitParticles (void)
48 int i;
50 i = COM_CheckParm ("-particles");
52 if (i)
54 r_numparticles = (int)(Q_atoi(com_argv[i+1]));
55 if (r_numparticles < ABSOLUTE_MIN_PARTICLES)
56 r_numparticles = ABSOLUTE_MIN_PARTICLES;
58 else
60 r_numparticles = MAX_PARTICLES;
63 particles = (particle_t *)
64 Hunk_AllocName (r_numparticles * sizeof(particle_t), "particles");
67 #ifdef QUAKE2
68 void R_DarkFieldParticles (entity_t *ent)
70 int i, j, k;
71 particle_t *p;
72 float vel;
73 vec3_t dir;
74 vec3_t org;
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)
83 if (!free_particles)
84 return;
85 p = free_particles;
86 free_particles = p->next;
87 p->next = active_particles;
88 active_particles = p;
90 p->die = cl.time + 0.2 + (rand()&7) * 0.02;
91 p->color = 150 + rand()%6;
92 p->type = pt_slowgrav;
94 dir[0] = j*8;
95 dir[1] = i*8;
96 dir[2] = k*8;
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);
107 #endif
111 ===============
112 R_EntityParticles
113 ===============
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)
126 int i;
127 particle_t *p;
128 float angle;
129 float sp, sy, cp, cy;
130 vec3_t forward;
131 float dist;
133 dist = 64;
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];
145 sy = sin(angle);
146 cy = cos(angle);
147 angle = cl.time * avelocities[i][1];
148 sp = sin(angle);
149 cp = cos(angle);
150 angle = cl.time * avelocities[i][2];
152 forward[0] = cp*cy;
153 forward[1] = cp*sy;
154 forward[2] = -sp;
156 if (!free_particles)
157 return;
158 p = free_particles;
159 free_particles = p->next;
160 p->next = active_particles;
161 active_particles = p;
163 p->die = cl.time + 0.01;
164 p->color = 0x6f;
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;
175 ===============
176 R_ClearParticles
177 ===============
179 void R_ClearParticles (void)
181 int i;
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)
194 FILE *f;
195 vec3_t org;
196 int r;
197 int c;
198 particle_t *p;
199 char name[MAX_OSPATH];
201 sprintf (name,"maps/%s.pts", sv.name);
203 COM_FOpenFile (name, &f);
204 if (!f)
206 Con_Printf ("couldn't open %s\n", name);
207 return;
210 Con_Printf ("Reading %s...\n", name);
211 c = 0;
212 for ( ;; )
214 r = fscanf (f,"%f %f %f\n", &org[0], &org[1], &org[2]);
215 if (r != 3)
216 break;
217 c++;
219 if (!free_particles)
221 Con_Printf ("Not enough free particles\n");
222 break;
224 p = free_particles;
225 free_particles = p->next;
226 p->next = active_particles;
227 active_particles = p;
229 p->die = 99999;
230 p->color = (-c)&15;
231 p->type = pt_static;
232 VectorCopy (vec3_origin, p->vel);
233 VectorCopy (org, p->org);
236 fclose (f);
237 Con_Printf ("%i points read\n", c);
241 ===============
242 R_ParseParticleEffect
244 Parse an effect out of the server message
245 ===============
247 void R_ParseParticleEffect (void)
249 vec3_t org, dir;
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 ();
259 if (msgcount == 255)
260 count = 1024;
261 else
262 count = msgcount;
264 R_RunParticleEffect (org, dir, color, count);
268 ===============
269 R_ParticleExplosion
271 ===============
273 void R_ParticleExplosion (vec3_t org)
275 int i, j;
276 particle_t *p;
278 for (i=0 ; i<1024 ; i++)
280 if (!free_particles)
281 return;
282 p = free_particles;
283 free_particles = p->next;
284 p->next = active_particles;
285 active_particles = p;
287 p->die = cl.time + 5;
288 p->color = ramp1[0];
289 p->ramp = rand()&3;
290 if (i & 1)
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;
299 else
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;
312 ===============
313 R_ParticleExplosion2
315 ===============
317 void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength)
319 int i, j;
320 particle_t *p;
321 int colorMod = 0;
323 for (i=0; i<512; i++)
325 if (!free_particles)
326 return;
327 p = free_particles;
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);
334 colorMod++;
336 p->type = pt_blob;
337 for (j=0 ; j<3 ; j++)
339 p->org[j] = org[j] + ((rand()%32)-16);
340 p->vel[j] = (rand()%512)-256;
346 ===============
347 R_BlobExplosion
349 ===============
351 void R_BlobExplosion (vec3_t org)
353 int i, j;
354 particle_t *p;
356 for (i=0 ; i<1024 ; i++)
358 if (!free_particles)
359 return;
360 p = free_particles;
361 free_particles = p->next;
362 p->next = active_particles;
363 active_particles = p;
365 p->die = cl.time + 1 + (rand()&8)*0.05;
367 if (i & 1)
369 p->type = pt_blob;
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;
377 else
379 p->type = pt_blob2;
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;
391 ===============
392 R_RunParticleEffect
394 ===============
396 void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count)
398 int i, j;
399 particle_t *p;
401 for (i=0 ; i<count ; i++)
403 if (!free_particles)
404 return;
405 p = free_particles;
406 free_particles = p->next;
407 p->next = active_particles;
408 active_particles = p;
410 if (count == 1024)
411 { // rocket explosion
412 p->die = cl.time + 5;
413 p->color = ramp1[0];
414 p->ramp = rand()&3;
415 if (i & 1)
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;
424 else
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;
434 else
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;
450 ===============
451 R_LavaSplash
453 ===============
455 void R_LavaSplash (vec3_t org)
457 int i, j, k;
458 particle_t *p;
459 float vel;
460 vec3_t dir;
462 for (i=-16 ; i<16 ; i++)
463 for (j=-16 ; j<16 ; j++)
464 for (k=0 ; k<1 ; k++)
466 if (!free_particles)
467 return;
468 p = free_particles;
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);
479 dir[2] = 256;
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);
492 ===============
493 R_TeleportSplash
495 ===============
497 void R_TeleportSplash (vec3_t org)
499 int i, j, k;
500 particle_t *p;
501 float vel;
502 vec3_t dir;
504 for (i=-16 ; i<16 ; i+=4)
505 for (j=-16 ; j<16 ; j+=4)
506 for (k=-24 ; k<32 ; k+=4)
508 if (!free_particles)
509 return;
510 p = free_particles;
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;
519 dir[0] = j*8;
520 dir[1] = i*8;
521 dir[2] = k*8;
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)
535 vec3_t vec;
536 float len;
537 int j;
538 particle_t *p;
539 int dec;
540 static int tracercount;
542 VectorSubtract (end, start, vec);
543 len = VectorNormalize (vec);
544 if (type < 128)
545 dec = 3;
546 else
548 dec = 1;
549 type -= 128;
552 while (len > 0)
554 len -= dec;
556 if (!free_particles)
557 return;
558 p = free_particles;
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;
566 switch (type)
568 case 0: // rocket trail
569 p->ramp = (rand()&3);
570 p->color = ramp3[(int)p->ramp];
571 p->type = pt_fire;
572 for (j=0 ; j<3 ; j++)
573 p->org[j] = start[j] + ((rand()%6)-3);
574 break;
576 case 1: // smoke smoke
577 p->ramp = (rand()&3) + 2;
578 p->color = ramp3[(int)p->ramp];
579 p->type = pt_fire;
580 for (j=0 ; j<3 ; j++)
581 p->org[j] = start[j] + ((rand()%6)-3);
582 break;
584 case 2: // blood
585 p->type = pt_grav;
586 p->color = 67 + (rand()&3);
587 for (j=0 ; j<3 ; j++)
588 p->org[j] = start[j] + ((rand()%6)-3);
589 break;
591 case 3:
592 case 5: // tracer
593 p->die = cl.time + 0.5;
594 p->type = pt_static;
595 if (type == 3)
596 p->color = 52 + ((tracercount&4)<<1);
597 else
598 p->color = 230 + ((tracercount&4)<<1);
600 tracercount++;
602 VectorCopy (start, p->org);
603 if (tracercount & 1)
605 p->vel[0] = 30*vec[1];
606 p->vel[1] = 30*-vec[0];
608 else
610 p->vel[0] = 30*-vec[1];
611 p->vel[1] = 30*vec[0];
613 break;
615 case 4: // slight blood
616 p->type = pt_grav;
617 p->color = 67 + (rand()&3);
618 for (j=0 ; j<3 ; j++)
619 p->org[j] = start[j] + ((rand()%6)-3);
620 len -= 3;
621 break;
623 case 6: // voor trail
624 p->color = 9*16 + 8 + (rand()&3);
625 p->type = pt_static;
626 p->die = cl.time + 0.3;
627 for (j=0 ; j<3 ; j++)
628 p->org[j] = start[j] + ((rand()&15)-8);
629 break;
633 VectorAdd (start, vec, start);
639 ===============
640 R_DrawParticles
641 ===============
643 extern cvar_t sv_gravity;
645 void R_DrawParticles (void)
647 particle_t *p, *kill;
648 float grav;
649 int i;
650 float time2, time3;
651 float time1;
652 float dvel;
653 float frametime;
655 #ifdef GLQUAKE
656 vec3_t up, right;
657 float scale;
659 GL_Bind(particletexture);
660 glEnable (GL_BLEND);
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);
666 #else
667 D_StartParticles ();
669 VectorScale (vright, xscaleshrink, r_pright);
670 VectorScale (vup, yscaleshrink, r_pup);
671 VectorCopy (vpn, r_ppn);
672 #endif
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;
678 dvel = 4*frametime;
680 for ( ;; )
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;
688 continue;
690 break;
693 for (p=active_particles ; p ; p=p->next)
695 for ( ;; )
697 kill = p->next;
698 if (kill && kill->die < cl.time)
700 p->next = kill->next;
701 kill->next = free_particles;
702 free_particles = kill;
703 continue;
705 break;
708 #ifdef GLQUAKE
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];
712 if (scale < 20)
713 scale = 1;
714 else
715 scale = 1 + scale * 0.004;
716 glColor3ubv ((byte *)&d_8to24table[(int)p->color]);
717 glTexCoord2f (0,0);
718 glVertex3fv (p->org);
719 glTexCoord2f (1,0);
720 glVertex3f (p->org[0] + up[0]*scale, p->org[1] + up[1]*scale, p->org[2] + up[2]*scale);
721 glTexCoord2f (0,1);
722 glVertex3f (p->org[0] + right[0]*scale, p->org[1] + right[1]*scale, p->org[2] + right[2]*scale);
723 #else
724 D_DrawParticle (p);
725 #endif
726 p->org[0] += p->vel[0]*frametime;
727 p->org[1] += p->vel[1]*frametime;
728 p->org[2] += p->vel[2]*frametime;
730 switch (p->type)
732 case pt_static:
733 break;
734 case pt_fire:
735 p->ramp += time1;
736 if (p->ramp >= 6)
737 p->die = -1;
738 else
739 p->color = ramp3[(int)p->ramp];
740 p->vel[2] += grav;
741 break;
743 case pt_explode:
744 p->ramp += time2;
745 if (p->ramp >=8)
746 p->die = -1;
747 else
748 p->color = ramp1[(int)p->ramp];
749 for (i=0 ; i<3 ; i++)
750 p->vel[i] += p->vel[i]*dvel;
751 p->vel[2] -= grav;
752 break;
754 case pt_explode2:
755 p->ramp += time3;
756 if (p->ramp >=8)
757 p->die = -1;
758 else
759 p->color = ramp2[(int)p->ramp];
760 for (i=0 ; i<3 ; i++)
761 p->vel[i] -= p->vel[i]*frametime;
762 p->vel[2] -= grav;
763 break;
765 case pt_blob:
766 for (i=0 ; i<3 ; i++)
767 p->vel[i] += p->vel[i]*dvel;
768 p->vel[2] -= grav;
769 break;
771 case pt_blob2:
772 for (i=0 ; i<2 ; i++)
773 p->vel[i] -= p->vel[i]*dvel;
774 p->vel[2] -= grav;
775 break;
777 case pt_grav:
778 #ifdef QUAKE2
779 p->vel[2] -= grav * 20;
780 break;
781 #endif
782 case pt_slowgrav:
783 p->vel[2] -= grav;
784 break;
788 #ifdef GLQUAKE
789 glEnd ();
790 glDisable (GL_BLEND);
791 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
792 #else
793 D_EndParticles ();
794 #endif