Concept
What's an efrag? At the most basic level it's just a marker that an entity (either static or not) is currently inhabiting a certain leaf in the world. GLQuake uses them for just static entities whereas software Quake uses them for both types.
The default efrags limit is a piddling 640, and we're going to go through the roof here and get rid of it entirely.
This code will work with both software and GLQuake.
The code
Before we start writing any code, the differences in the two engines means that there are two different code files that handle efrags: gl_refrag.c for GLQuake and r_efrag.c for software Quake. Look at the two files, observe that there's only fairly minor differences between them, observe that the additional code in r_efrag.c has no impact whatsoever on GLQuake.
You could just use r_efrag.c for both, or you could keep them separate if you wish, or you may only maintain one of software or GLQuake. It's entirely up to you, but the code changes are identical for both versions.
On to the code. Open up your chosen efrags file and add this at the top:
Code: Select all
// mh - extended efrags - begin
#define EXTRA_EFRAGS 32
void R_GetMoreEfrags (void)
{
int i;
cl.free_efrags = (efrag_t *) Hunk_Alloc (EXTRA_EFRAGS * sizeof (efrag_t));
for (i = 0; i < EXTRA_EFRAGS - 1; i++)
cl.free_efrags[i].entnext = &cl.free_efrags[i + 1];
cl.free_efrags[i].entnext = NULL;
}
// mh - extended efrags - end
Code: Select all
if (!ef)
{
// mh - extended efrags - begin
R_GetMoreEfrags ();
ef = cl.free_efrags;
// mh - extended efrags - end
}
What's really nice about this extension is that it can quite easily be tested by setting your value of MAX_EFRAGS to something like 2, adding a Con_Printf to R_GetMoreEfrags, and just running a map.
Cleaning up
There's not much to be done here to be honest. You might like to change the name of MAX_EFRAGS to something like INITIAL_EFRAGS and maybe even reduce it's value (so that you're not wasting memory on efrags you may not need), or you might like to remove it entirely, set cl.free_efrags to NULL (instead of to cl_efrags) in your CL_ClearState function, and let R_GetMoreEfrags do all the work.
I would have constructed this tutorial around the last way but I like to keep all code-changes in a single file if at all possible.
A Note on Memory Usage
With both this tutorial and with my previous one we're allocating extra objects off the Hunk which will put some pressure on the memory Quake has available to run in. You should either increase the default heapsize a little or use my Quake Memory Manager tutorials (or similar) to avoid any issues from this.
The bottom line though is that the memory for the extra objects has to come from somewhere, and the Hunk is convenient as it is cleared automatically between map loads and will handle error checking for us.