+ R_DecalSystem_SplatEntity(ent, worldorigin, worldnormal, r, g, b, a, s1, t1, s2, t2, worldsize, decalsequence);
+ }
+}
+
+typedef struct r_decalsystem_splatqueue_s
+{
+ vec3_t worldorigin;
+ vec3_t worldnormal;
+ float color[4];
+ float tcrange[4];
+ float worldsize;
+ int decalsequence;
+}
+r_decalsystem_splatqueue_t;
+
+int r_decalsystem_numqueued = 0;
+#define MAX_DECALSYSTEM_QUEUE 1024
+r_decalsystem_splatqueue_t r_decalsystem_queue[MAX_DECALSYSTEM_QUEUE];
+
+void R_DecalSystem_SplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize)
+{
+ r_decalsystem_splatqueue_t *queue;
+
+ if (!cl_decals_newsystem.integer || r_decalsystem_numqueued == MAX_DECALSYSTEM_QUEUE)
+ return;
+
+ queue = &r_decalsystem_queue[r_decalsystem_numqueued++];
+ VectorCopy(worldorigin, queue->worldorigin);
+ VectorCopy(worldnormal, queue->worldnormal);
+ Vector4Set(queue->color, r, g, b, a);
+ Vector4Set(queue->tcrange, s1, t1, s2, t2);
+ queue->worldsize = worldsize;
+ queue->decalsequence = cl.decalsequence++;
+}
+
+static void R_DecalSystem_ApplySplatEntitiesQueue(void)
+{
+ int i;
+ r_decalsystem_splatqueue_t *queue;
+
+ for (i = 0, queue = r_decalsystem_queue;i < r_decalsystem_numqueued;i++, queue++)
+ R_DecalSystem_ApplySplatEntities(queue->worldorigin, queue->worldnormal, queue->color[0], queue->color[1], queue->color[2], queue->color[3], queue->tcrange[0], queue->tcrange[1], queue->tcrange[2], queue->tcrange[3], queue->worldsize, queue->decalsequence);
+ r_decalsystem_numqueued = 0;
+}
+
+extern cvar_t cl_decals_max;
+static void R_DrawModelDecals_FadeEntity(entity_render_t *ent)
+{
+ int i;
+ decalsystem_t *decalsystem = &ent->decalsystem;
+ int numdecals;
+ int killsequence;
+ tridecal_t *decal;
+ float frametime;
+ float lifetime;
+
+ if (!decalsystem->numdecals)
+ return;
+
+ if (r_showsurfaces.integer)
+ return;
+
+ if (ent->model != decalsystem->model || ent->alpha < 1 || (ent->flags & RENDER_ADDITIVE))
+ {
+ R_DecalSystem_Reset(decalsystem);
+ return;
+ }
+
+ killsequence = cl.decalsequence - max(1, cl_decals_max.integer);
+ lifetime = cl_decals_time.value + cl_decals_fadetime.value;
+
+ if (decalsystem->lastupdatetime)
+ frametime = (cl.time - decalsystem->lastupdatetime);
+ else
+ frametime = 0;
+ decalsystem->lastupdatetime = cl.time;
+ decal = decalsystem->decals;
+ numdecals = decalsystem->numdecals;
+
+ for (i = 0, decal = decalsystem->decals;i < numdecals;i++, decal++)
+ {
+ if (decal->color4ub[0][3])
+ {
+ decal->lived += frametime;
+ if (killsequence - decal->decalsequence > 0 || decal->lived >= lifetime)
+ {
+ memset(decal, 0, sizeof(*decal));
+ if (decalsystem->freedecal > i)
+ decalsystem->freedecal = i;
+ }
+ }
+ }
+ decal = decalsystem->decals;
+ while (numdecals > 0 && !decal[numdecals-1].color4ub[0][3])
+ numdecals--;
+
+ // collapse the array by shuffling the tail decals into the gaps
+ for (;;)
+ {
+ while (decalsystem->freedecal < numdecals && decal[decalsystem->freedecal].color4ub[0][3])
+ decalsystem->freedecal++;
+ if (decalsystem->freedecal == numdecals)
+ break;
+ decal[decalsystem->freedecal] = decal[--numdecals];
+ }
+
+ decalsystem->numdecals = numdecals;
+
+ if (numdecals <= 0)
+ {
+ // if there are no decals left, reset decalsystem
+ R_DecalSystem_Reset(decalsystem);