Forum

Removing the hard-coded limit on the number of particles

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

Removing the hard-coded limit on the number of particles

Postby mh » Wed Jul 23, 2008 6:38 pm

I can't find a "Tutorials" section (aside from QC stuff) so apologies in advance for posting it here. This must rank as the easiest change to the engine ever, will work for both WinQuake and GLQuake, and is a good thing to have.

It assumes that you're reasonably familiar with r_part.c, or at least with the general layout of it, and it's not going to teach you how to program, but otherwise it's pure copy-and-paste.

At the top of the file:
Code: Select all
#define PARTICLE_BATCH_SIZE      2048
#define PARTICLE_EXTRA_SIZE      1024


Your new R_InitParticles function (yes, this is no joke):
Code: Select all
void R_InitParticles (void)
{
}


Your new R_ClearParticles function:
Code: Select all
void R_ClearParticles (void)
{
   int      i;
   
   free_particles = (particle_t *) Hunk_AllocName (PARTICLE_BATCH_SIZE * sizeof (particle_t), "particles");
   active_particles = NULL;

   for (i = 0; i < PARTICLE_BATCH_SIZE; i++)
      free_particles[i].next = &free_particles[i + 1];

   free_particles[PARTICLE_BATCH_SIZE - 1].next = NULL;
}


The only new function you need, ladies and gents I give you the mighty R_NewParticle:
Code: Select all
particle_t *R_NewParticle (void)
{
   particle_t   *p;
   int i;

   if (free_particles)
   {
      // just take from the free list
      p = free_particles;
      free_particles = p->next;
      p->next = active_particles;
      active_particles = p;

      return p;
   }
   else
   {
      // alloc some more free particles
      free_particles = (particle_t *) Hunk_AllocName (PARTICLE_EXTRA_SIZE * sizeof (particle_t), "particles");

      // link them up
      for (i = 0; i < PARTICLE_EXTRA_SIZE; i++)
         free_particles[i].next = &free_particles[i + 1];

      // finish the link
      free_particles[PARTICLE_EXTRA_SIZE - 1].next = NULL;

      // call recursively to return the first new free particle
      return R_NewParticle ();
   }
}


And finally, replace every occurrance of this:
Code: Select all
   if (!free_particles)
      return;
   p = free_particles;
   free_particles = p->next;
   p->next = active_particles;
   active_particles = p;


With this:
Code: Select all
   p = R_NewParticle ();


Job done. The only room for refinement is that the two memory allocations could be refactored as a single function. You might also want to write your own version of Hunk_AllocName that doesn't memset to 0 for extra performance.

Now you can allocate as many particles as you want until you run out of memory. And because the hunk is cleared between maps, any extra won't carry over.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Labman » Thu Jul 24, 2008 10:27 am

But do you really need that many particles when they look so crappy anyway. I guess it makes sense if you have a semi customised particle system to go with it.
Labman
 
Posts: 62
Joined: Fri Nov 05, 2004 2:39 am
Location: Cambridge, United Kingdom

Postby MeTcHsteekle » Thu Jul 24, 2008 12:23 pm

hey more paricales = more blood :D
bah
MeTcHsteekle
 
Posts: 399
Joined: Thu May 15, 2008 10:46 pm
Location: its a secret

Postby mh » Thu Jul 24, 2008 7:06 pm

Do you really need that many particles when they look so crappy anyway? Depends. If you look at the numbers, Quake out of the box only supports 2048, which - in GLQuake - is enough for two explosions and nothing more (that's why I chose 1024 as the extra number - chances are if you run out of particles it's most likely because you have an explosion incoming, no other effect uses as many). OK, they may look crap but let's not make them look any crapper. :wink:

You can work around it with -particles, but that requires an engine restart and is still a hard limit anyway.

Very very handy for loading pointfiles too. This is one engine feature I'm sure mappers would applaud.

Finally, removing internal hard limits is a good thing in itself. :D
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am


Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest