struct particle_batcher {
private:
int bmap_id;
int bmap_nframes;
geometry_batcher *bmap_batchers;
For each particle animation. Whenever a new particle is created, the vector of particle_batchers is checked for an entry corresponding to the new particle's animation. It automatically grabs the first frame of the animation using bm_get_info(), so there are no duplicate entries (hopefully). If it can't find a set of geometry batchers for the new particle's animation, it pushes another particle_batcher entry onto the Batchers vector. The index into the Batchers[] vector is then saved in the particle struct, and is used to batch render the frames in particle_render_all().
The result is that the particle system gets a lot cleaner and has a lot less duplicate code, and more fine control is possible than while using the ordinary batch_render system. My guess is that it may be slightly faster, but probably not noticeable, because it doesn't have to look for a geometry_batcher each frame; it already has the index right there in the particle struct, so it just has to do a subtraction operation to figure out where in the array to put it.
Also, I think this build may have some kind of compilation errors. I noticed some bizarre model, ship select, and trail issues, did a rebuild of the solution, and they disappeared.