git-svn-id: http://bladebattles.com/kurok/SVN@11 20cd92bb-ff49-0410-b73e-96a06e42c3b9
[kurok.git] / r_part.c
blobc57d9c97f8aac5e06990786818e76db1e3217e79
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 1024 // 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, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
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 count;
127 int i;
128 particle_t *p;
129 float angle;
130 float sr, sp, sy, cr, cp, cy;
131 vec3_t forward;
132 float dist;
134 dist = 64;
135 count = 25; //50;
137 if (!avelocities[0][0])
139 for (i=0 ; i<NUMVERTEXNORMALS*3 ; i++)
140 avelocities[0][i] = (rand()&255) * 0.01;
144 for (i=0 ; i<NUMVERTEXNORMALS ; i++)
146 angle = cl.time * avelocities[i][0];
147 sy = sinf(angle);
148 cy = cosf(angle);
149 angle = cl.time * avelocities[i][1];
150 sp = sinf(angle);
151 cp = cosf(angle);
152 angle = cl.time * avelocities[i][2];
153 sr = sinf(angle);
154 cr = cosf(angle);
156 forward[0] = cp*cy;
157 forward[1] = cp*sy;
158 forward[2] = -sp;
160 if (!free_particles)
161 return;
162 p = free_particles;
163 free_particles = p->next;
164 p->next = active_particles;
165 active_particles = p;
167 p->die = cl.time + 0.01;
168 p->color = 0x6f;
169 p->type = pt_explode;
171 p->org[0] = ent->origin[0] + r_avertexnormals[i][0]*dist + forward[0]*beamlength;
172 p->org[1] = ent->origin[1] + r_avertexnormals[i][1]*dist + forward[1]*beamlength;
173 p->org[2] = ent->origin[2] + r_avertexnormals[i][2]*dist + forward[2]*beamlength;
179 ===============
180 R_ClearParticles
181 ===============
183 void R_ClearParticles (void)
185 int i;
187 free_particles = &particles[0];
188 active_particles = NULL;
190 for (i=0 ;i<r_numparticles ; i++)
191 particles[i].next = &particles[i+1];
192 particles[r_numparticles-1].next = NULL;
196 void R_ReadPointFile_f (void)
198 int f;
199 vec3_t org;
200 int r;
201 int c;
202 particle_t *p;
203 char name[MAX_OSPATH];
205 sprintf (name,"maps/%s.pts", sv.name);
207 COM_FOpenFile (name, &f);
208 if (f < 0)
210 Con_Printf ("couldn't open %s\n", name);
211 return;
214 Con_Printf ("Reading %s...\n", name);
215 c = 0;
216 for ( ;; )
218 // Read the line into a string.
219 char line[128];
220 int chars = 0;
223 if (chars >= (sizeof(line) - 2))
225 Sys_Error("Line buffer overflow when reading point file");
228 if (!Sys_FileRead(f, &line[chars++], 1) != 1)
230 break;
233 while (line[chars - 1] != '\n');
234 line[chars] = '\0';
236 r = sscanf (line, "%f %f %f\n", &org[0], &org[1], &org[2]);
237 if (r != 3)
238 break;
239 c++;
241 if (!free_particles)
243 Con_Printf ("Not enough free particles\n");
244 break;
246 p = free_particles;
247 free_particles = p->next;
248 p->next = active_particles;
249 active_particles = p;
251 p->die = 99999;
252 p->color = (-c)&15;
253 p->type = pt_static;
254 VectorCopy (vec3_origin, p->vel);
255 VectorCopy (org, p->org);
258 Sys_FileClose(f);
259 Con_Printf ("%i points read\n", c);
263 ===============
264 R_ParseParticleEffect
266 Parse an effect out of the server message
267 ===============
269 void R_ParseParticleEffect (void)
271 vec3_t org, dir;
272 int i, count, msgcount, color;
274 for (i=0 ; i<3 ; i++)
275 org[i] = MSG_ReadCoord ();
276 for (i=0 ; i<3 ; i++)
277 dir[i] = MSG_ReadChar () * (1.0/16);
278 msgcount = MSG_ReadByte ();
279 color = MSG_ReadByte ();
281 if (msgcount == 255)
282 count = 1024;
283 else
284 count = msgcount;
286 R_RunParticleEffect (org, dir, color, count);
290 ===============
291 R_ParticleExplosion
293 ===============
295 void R_ParticleExplosion (vec3_t org)
297 int i, j;
298 particle_t *p;
300 for (i=0 ; i<1024 ; i++)
302 if (!free_particles)
303 return;
304 p = free_particles;
305 free_particles = p->next;
306 p->next = active_particles;
307 active_particles = p;
309 p->die = cl.time + 5;
310 p->color = ramp1[0];
311 p->ramp = rand()&3;
312 if (i & 1)
314 p->type = pt_explode;
315 for (j=0 ; j<3 ; j++)
317 p->org[j] = org[j] + ((rand()%32)-16);
318 p->vel[j] = (rand()%512)-256;
321 else
323 p->type = pt_explode2;
324 for (j=0 ; j<3 ; j++)
326 p->org[j] = org[j] + ((rand()%32)-16);
327 p->vel[j] = (rand()%512)-256;
334 ===============
335 R_ParticleExplosion2
337 ===============
339 void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength)
341 int i, j;
342 particle_t *p;
343 int colorMod = 0;
345 for (i=0; i<512; i++)
347 if (!free_particles)
348 return;
349 p = free_particles;
350 free_particles = p->next;
351 p->next = active_particles;
352 active_particles = p;
354 p->die = cl.time + 0.3;
355 p->color = colorStart + (colorMod % colorLength);
356 colorMod++;
358 p->type = pt_blob;
359 for (j=0 ; j<3 ; j++)
361 p->org[j] = org[j] + ((rand()%32)-16);
362 p->vel[j] = (rand()%512)-256;
368 ===============
369 R_BlobExplosion
371 ===============
373 void R_BlobExplosion (vec3_t org)
375 int i, j;
376 particle_t *p;
378 for (i=0 ; i<1024 ; i++)
380 if (!free_particles)
381 return;
382 p = free_particles;
383 free_particles = p->next;
384 p->next = active_particles;
385 active_particles = p;
387 p->die = cl.time + 1 + (rand()&8)*0.05;
389 if (i & 1)
391 p->type = pt_blob;
392 p->color = 66 + rand()%6;
393 for (j=0 ; j<3 ; j++)
395 p->org[j] = org[j] + ((rand()%32)-16);
396 p->vel[j] = (rand()%512)-256;
399 else
401 p->type = pt_blob2;
402 p->color = 150 + rand()%6;
403 for (j=0 ; j<3 ; j++)
405 p->org[j] = org[j] + ((rand()%32)-16);
406 p->vel[j] = (rand()%512)-256;
413 ===============
414 R_RunParticleEffect
416 ===============
418 void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count)
420 int i, j;
421 particle_t *p;
423 for (i=0 ; i<count ; i++)
425 if (!free_particles)
426 return;
427 p = free_particles;
428 free_particles = p->next;
429 p->next = active_particles;
430 active_particles = p;
432 if (count == 1024)
433 { // rocket explosion
434 p->die = cl.time + 5;
435 p->color = ramp1[0];
436 p->ramp = rand()&3;
437 if (i & 1)
439 p->type = pt_explode;
440 for (j=0 ; j<3 ; j++)
442 p->org[j] = org[j] + ((rand()%32)-16);
443 p->vel[j] = (rand()%512)-256;
446 else
448 p->type = pt_explode2;
449 for (j=0 ; j<3 ; j++)
451 p->org[j] = org[j] + ((rand()%32)-16);
452 p->vel[j] = (rand()%512)-256;
456 else
458 p->die = cl.time + 0.1*(rand()%5);
459 p->color = (color&~7) + (rand()&7);
460 p->type = pt_slowgrav;
461 for (j=0 ; j<3 ; j++)
463 p->org[j] = org[j] + ((rand()&15)-8);
464 p->vel[j] = dir[j]*15;// + (rand()%300)-150;
472 ===============
473 R_LavaSplash
475 ===============
477 void R_LavaSplash (vec3_t org)
479 int i, j, k;
480 particle_t *p;
481 float vel;
482 vec3_t dir;
484 for (i=-16 ; i<16 ; i++)
485 for (j=-16 ; j<16 ; j++)
486 for (k=0 ; k<1 ; k++)
488 if (!free_particles)
489 return;
490 p = free_particles;
491 free_particles = p->next;
492 p->next = active_particles;
493 active_particles = p;
495 p->die = cl.time + 2 + (rand()&31) * 0.02;
496 p->color = 224 + (rand()&7);
497 p->type = pt_slowgrav;
499 dir[0] = j*8 + (rand()&7);
500 dir[1] = i*8 + (rand()&7);
501 dir[2] = 256;
503 p->org[0] = org[0] + dir[0];
504 p->org[1] = org[1] + dir[1];
505 p->org[2] = org[2] + (rand()&63);
507 VectorNormalize (dir);
508 vel = 50 + (rand()&63);
509 VectorScale (dir, vel, p->vel);
514 ===============
515 R_TeleportSplash
517 ===============
519 void R_TeleportSplash (vec3_t org)
521 int i, j, k;
522 particle_t *p;
523 float vel;
524 vec3_t dir;
526 for (i=-16 ; i<16 ; i+=4)
527 for (j=-16 ; j<16 ; j+=4)
528 for (k=-24 ; k<32 ; k+=4)
530 if (!free_particles)
531 return;
532 p = free_particles;
533 free_particles = p->next;
534 p->next = active_particles;
535 active_particles = p;
537 p->die = cl.time + 0.2 + (rand()&7) * 0.02;
538 p->color = 7 + (rand()&7);
539 p->type = pt_slowgrav;
541 dir[0] = j*8;
542 dir[1] = i*8;
543 dir[2] = k*8;
545 p->org[0] = org[0] + i + (rand()&3);
546 p->org[1] = org[1] + j + (rand()&3);
547 p->org[2] = org[2] + k + (rand()&3);
549 VectorNormalize (dir);
550 vel = 50 + (rand()&63);
551 VectorScale (dir, vel, p->vel);
555 void R_RocketTrail (vec3_t start, vec3_t end, int type)
557 vec3_t vec;
558 float len;
559 int j;
560 particle_t *p;
561 int dec;
562 static int tracercount;
564 VectorSubtract (end, start, vec);
565 len = VectorNormalize (vec);
566 if (type < 128)
567 dec = 3;
568 else
570 dec = 1;
571 type -= 128;
574 while (len > 0)
576 len -= dec;
578 if (!free_particles)
579 return;
580 p = free_particles;
581 free_particles = p->next;
582 p->next = active_particles;
583 active_particles = p;
585 VectorCopy (vec3_origin, p->vel);
586 p->die = cl.time + 2;
588 switch (type)
590 case 0: // rocket trail
591 p->ramp = (rand()&3);
592 p->color = ramp3[(int)p->ramp];
593 p->type = pt_fire;
594 for (j=0 ; j<3 ; j++)
595 p->org[j] = start[j] + ((rand()%6)-3);
596 break;
598 case 1: // smoke smoke
599 p->ramp = (rand()&3) + 2;
600 p->color = ramp3[(int)p->ramp];
601 p->type = pt_fire;
602 for (j=0 ; j<3 ; j++)
603 p->org[j] = start[j] + ((rand()%6)-3);
604 break;
606 case 2: // blood
607 p->type = pt_grav;
608 p->color = 67 + (rand()&3);
609 for (j=0 ; j<3 ; j++)
610 p->org[j] = start[j] + ((rand()%6)-3);
611 break;
613 case 3:
614 case 5: // tracer
615 p->die = cl.time + 0.5;
616 p->type = pt_static;
617 if (type == 3)
618 p->color = 52 + ((tracercount&4)<<1);
619 else
620 p->color = 230 + ((tracercount&4)<<1);
622 tracercount++;
624 VectorCopy (start, p->org);
625 if (tracercount & 1)
627 p->vel[0] = 30*vec[1];
628 p->vel[1] = 30*-vec[0];
630 else
632 p->vel[0] = 30*-vec[1];
633 p->vel[1] = 30*vec[0];
635 break;
637 case 4: // slight blood
638 p->type = pt_grav;
639 p->color = 67 + (rand()&3);
640 for (j=0 ; j<3 ; j++)
641 p->org[j] = start[j] + ((rand()%6)-3);
642 len -= 3;
643 break;
645 case 6: // voor trail
646 p->color = 9*16 + 8 + (rand()&3);
647 p->type = pt_static;
648 p->die = cl.time + 0.3;
649 for (j=0 ; j<3 ; j++)
650 p->org[j] = start[j] + ((rand()&15)-8);
651 break;
655 VectorAdd (start, vec, start);
661 ===============
662 R_DrawParticles
663 ===============
665 extern cvar_t sv_gravity;
667 #define PART_BUFFER_SIZE 1024
669 void R_DrawParticles (void)
671 particle_t *p, *kill;
672 float grav;
673 int i;
674 float time2, time3;
675 float time1;
676 float dvel;
677 float frametime;
678 vec3_t up, right;
679 float scale;
681 #ifdef PSP_HARDWARE_VIDEO
683 int part_buffer_size = PART_BUFFER_SIZE;
684 psp_particle* part_buffer = NULL;
685 part_buffer = D_CreateBuffer(part_buffer_size);
687 VectorScale (vup, 1.25, up);
688 VectorScale (vright, 1.25, right);
689 #endif
690 D_StartParticles ();
692 #ifdef PSP_HARDWARE_VIDEO
693 //VectorScale (vright, xscaleshrink, r_pright);
694 //VectorScale (vup, yscaleshrink, r_pup);
695 //VectorCopy (vright, r_pright);
696 //VectorCopy (vup, r_pup);
697 #else
698 VectorScale (vright, xscaleshrink, r_pright);
699 VectorScale (vup, yscaleshrink, r_pup);
700 #endif
701 VectorCopy (vpn, r_ppn);
703 frametime = cl.time - cl.oldtime;
704 time3 = frametime * 15;
705 time2 = frametime * 10; // 15;
706 time1 = frametime * 5;
707 grav = frametime * sv_gravity.value * 0.05;
708 dvel = 4*frametime;
710 for ( ;; )
712 kill = active_particles;
713 if (kill && kill->die < cl.time)
715 active_particles = kill->next;
716 kill->next = free_particles;
717 free_particles = kill;
718 continue;
720 break;
723 for (p=active_particles ; p ; p=p->next)
725 for ( ;; )
727 kill = p->next;
728 if (kill && kill->die < cl.time)
730 p->next = kill->next;
731 kill->next = free_particles;
732 free_particles = kill;
733 continue;
735 break;
738 #ifdef PSP_HARDWARE_VIDEO
739 // hack a scale up to keep particles from disapearing
740 scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
741 + (p->org[2] - r_origin[2])*vpn[2];
742 if (scale < 20)
743 scale = 1;
744 else
745 scale = 1 + scale * 0.004;
747 // D_DrawParticle (p, up, right, scale);
748 int rv = D_DrawParticleBuffered(part_buffer,p, up, right, scale);
749 if (rv == -1)
750 part_buffer = D_CreateBuffer(part_buffer_size);
752 #else
753 D_DrawParticle (p);
754 #endif
755 p->org[0] += p->vel[0]*frametime;
756 p->org[1] += p->vel[1]*frametime;
757 p->org[2] += p->vel[2]*frametime;
759 switch (p->type)
761 case pt_static:
762 break;
763 case pt_fire:
764 p->ramp += time1;
765 if (p->ramp >= 6)
766 p->die = -1;
767 else
768 p->color = ramp3[(int)p->ramp];
769 p->vel[2] += grav;
770 break;
772 case pt_explode:
773 p->ramp += time2;
774 if (p->ramp >=8)
775 p->die = -1;
776 else
777 p->color = ramp1[(int)p->ramp];
778 for (i=0 ; i<3 ; i++)
779 p->vel[i] += p->vel[i]*dvel;
780 p->vel[2] -= grav;
781 break;
783 case pt_explode2:
784 p->ramp += time3;
785 if (p->ramp >=8)
786 p->die = -1;
787 else
788 p->color = ramp2[(int)p->ramp];
789 for (i=0 ; i<3 ; i++)
790 p->vel[i] -= p->vel[i]*frametime;
791 p->vel[2] -= grav;
792 break;
794 case pt_blob:
795 for (i=0 ; i<3 ; i++)
796 p->vel[i] += p->vel[i]*dvel;
797 p->vel[2] -= grav;
798 break;
800 case pt_blob2:
801 for (i=0 ; i<2 ; i++)
802 p->vel[i] -= p->vel[i]*dvel;
803 p->vel[2] -= grav;
804 break;
806 case pt_grav:
807 #ifdef QUAKE2
808 p->vel[2] -= grav * 20;
809 break;
810 #endif
811 case pt_slowgrav:
812 p->vel[2] -= grav;
813 break;
816 #ifdef PSP_HARDWARE_VIDEO
817 D_DeleteBuffer(part_buffer);
818 #endif
819 D_EndParticles ();