Removing the hard-coded limit on the number of particles
Moderator: InsideQC Admins
4 posts
• Page 1 of 1
Removing the hard-coded limit on the number of particles
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:
Your new R_InitParticles function (yes, this is no joke):
Your new R_ClearParticles function:
The only new function you need, ladies and gents I give you the mighty R_NewParticle:
And finally, replace every occurrance of this:
With this:
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.
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
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
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.
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.
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.
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
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
4 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest