4 #include "cl_collision.h"
6 #define CGVM_RENDERENTITIES 1024
8 static entity_render_t cgvm_renderentities[CGVM_RENDERENTITIES];
9 static int cgvm_renderentity;
11 static mempool_t *cgvm_mempool;
13 static void (*cgvm_networkcode[256])(unsigned char num);
15 static qbyte *cgvm_netbuffer;
16 static int cgvm_netbufferlength;
17 static int cgvm_netbufferpos;
19 #define MAX_CGVM_MODELS 128
20 #define MAX_CGVM_MODELNAME 32
21 static char cgvm_modelname[MAX_CGVM_MODELS][MAX_CGVM_MODELNAME];
22 static model_t *cgvm_model[MAX_CGVM_MODELS];
24 void CL_CGVM_Init(void)
26 cgvm_mempool = Mem_AllocPool("CGVM");
29 void CL_CGVM_Clear(void)
31 Mem_EmptyPool(cgvm_mempool);
32 memset(cgvm_networkcode, 0, sizeof(cgvm_networkcode));
33 memset(cgvm_modelname, 0, sizeof(cgvm_modelname));
34 memset(cgvm_model, 0, sizeof(cgvm_model));
37 void CL_CGVM_Frame(void)
39 cgvm_renderentity = 0;
40 CG_Frame(cl.time); // API call
43 // starts the cgame code
44 void CL_CGVM_Start(void)
47 CG_Init(); // API call
50 void CL_CGVM_ParseNetwork(qbyte *netbuffer, int length)
53 cgvm_netbuffer = netbuffer;
54 cgvm_netbufferlength = length;
55 cgvm_netbufferpos = 0;
56 while (cgvm_netbufferpos < cgvm_netbufferlength)
58 num = CGVM_MSG_ReadByte();
59 if (cgvm_networkcode[num])
60 cgvm_networkcode[num]((qbyte)num);
62 Host_Error("CL_CGVM_ParseNetwork: unregistered network code %i", num);
73 void CGVM_RegisterNetworkCode(const unsigned char num, void (*netcode)(unsigned char num))
75 if (cgvm_networkcode[num])
76 Host_Error("CGVM_RegisterNetworkCode: value %i already registered", num);
77 cgvm_networkcode[num] = netcode;
80 unsigned char CGVM_MSG_ReadByte(void)
82 if (cgvm_netbufferpos < cgvm_netbufferlength)
83 return cgvm_netbuffer[cgvm_netbufferpos++];
88 short CGVM_MSG_ReadShort(void)
91 num = CGVM_MSG_ReadByte() | (CGVM_MSG_ReadByte() << 8);
95 int CGVM_MSG_ReadLong(void)
98 num = CGVM_MSG_ReadByte() | (CGVM_MSG_ReadByte() << 8) | (CGVM_MSG_ReadByte() << 16) | (CGVM_MSG_ReadByte() << 24);
102 float CGVM_MSG_ReadFloat(void)
105 num = CGVM_MSG_ReadByte() | (CGVM_MSG_ReadByte() << 8) | (CGVM_MSG_ReadByte() << 16) | (CGVM_MSG_ReadByte() << 24);
106 return *((float *)&num);
109 float CGVM_MSG_ReadCoord(void)
111 return CGVM_MSG_ReadFloat();
114 float CGVM_MSG_ReadAngle(void)
116 return CGVM_MSG_ReadByte() * 360.0f / 256.0f;
119 float CGVM_MSG_ReadPreciseAngle(void)
121 return ((unsigned short)CGVM_MSG_ReadShort()) * 360.0f / 65536.0f;
124 void CGVM_Draw_Entity(const cgdrawentity_t *e)
127 //Con_Printf("CGVM_Draw_Entity: origin %f %f %f angles %f %f %f alpha %f scale %f model %i frame1 %i frame2 %i framelerp %f skinnum %i\n", e->origin[0], e->origin[1], e->origin[2], e->angles[0], e->angles[1], e->angles[2], e->alpha, e->scale, e->model, e->frame1, e->frame2, e->framelerp, e->skinnum);
132 if (cgvm_renderentity >= CGVM_RENDERENTITIES
133 || r_refdef.numentities >= r_refdef.maxentities)
136 r = cgvm_renderentities + cgvm_renderentity;
137 VectorCopy(e->origin, r->origin);
138 VectorCopy(e->angles, r->angles);
141 if (e->model < 0 || e->model >= MAX_CGVM_MODELS || !cgvm_model[e->model])
143 Con_Printf("CGVM_Draw_Entity: invalid model index %i\n", e->model);
146 r->model = cgvm_model[e->model];
148 r->frame = e->frame2;
149 // FIXME: support colormapping?
151 // FIXME: support effects?
153 r->skinnum = e->skinnum;
154 // FIXME: any flags worth setting?
157 r->frame1 = e->frame1;
158 r->frame2 = e->frame2;
159 r->framelerp = e->framelerp;
163 r_refdef.entities[r_refdef.numentities++] = r;
168 void CGVM_Draw_Light(const cgdrawlight_t *l)
170 CL_AllocDlight(NULL, (float *) l->origin, 1, l->light[0], l->light[1], l->light[2], 0, 0);
173 void *CGVM_Malloc(const int size)
175 return Mem_Alloc(cgvm_mempool, size);
178 void CGVM_Free(void *mem)
183 float CGVM_RandomRange(const float r1, const float r2)
185 return lhrandom(r1, r2);
188 float CGVM_TracePhysics(const float *start, const float *end, const float *worldmins, const float *worldmaxs, const float *entitymins, const float *entitymaxs, const cgphysentity_t *physentities, const int numphysentities, float *impactpos, float *impactnormal, int *impactentnum)
191 vec3_t start2, end2, middle;
192 // FIXME: do tracing agains network entities and physentities here
193 // placeholder world only code assuming 0 size
194 middle[0] = (worldmins[0] + worldmaxs[0]) * 0.5f;
195 middle[1] = (worldmins[1] + worldmaxs[1]) * 0.5f;
196 middle[2] = (worldmins[2] + worldmaxs[2]) * 0.5f;
197 VectorAdd(start, middle, start2);
198 VectorAdd(end, middle, end2);
199 frac = CL_TraceLine((float *)start2, (float *)end2, impactpos, impactnormal, 0, true, NULL);
200 VectorSubtract(impactpos, middle, impactpos);
205 char *CGVM_GetCvarString(const char *name)
208 cvar = Cvar_FindVar((char *)name);
215 float CGVM_GetCvarFloat(const char *name)
218 cvar = Cvar_FindVar((char *)name);
225 int CGVM_GetCvarInt(const char *name)
228 cvar = Cvar_FindVar((char *)name);
230 return cvar->integer;
235 double CGVM_Time(void)
240 int CGVM_Model(const char *name)
244 if (strlen(name) > (MAX_CGVM_MODELNAME - 1))
246 for (i = 1;i < MAX_CGVM_MODELS;i++)
248 if (!cgvm_modelname[i][0])
250 if (!strcmp(name, cgvm_modelname[i]))
253 if (i >= MAX_CGVM_MODELS)
255 model = Mod_ForName((char *)name, false, false, false);
258 strcpy(cgvm_modelname[i], name);
259 cgvm_model[i] = model;
263 void CGVM_Stain(const float *origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2)
265 if (cl_stainmaps.integer)
266 R_Stain((float *)origin, radius, cr1, cg1, cb1, ca1, cr2, cg2, cb2, ca2);