4 #define HunkAlloc BADGDFG sdfhhsf FHS
6 void PR_SetBuiltins(int type);
8 progstate_t *pr_progstate;
9 progsnum_t pr_typecurrent;
12 progstate_t *current_progstate;
15 sharedvar_t *shares; //shared globals, not including parms
19 pbool PR_SwitchProgs(progfuncs_t *progfuncs, progsnum_t type)
21 if ((unsigned)type >= maxprogs)
22 PR_RunError(progfuncs, "QCLIB: Bad prog type - %i", type);
23 // Sys_Error("Bad prog type - %i", type);
25 if (pr_progstate[(unsigned)type].progs == NULL) //we havn't loaded it yet, for some reason
28 current_progstate = &pr_progstate[(unsigned)type];
30 pr_typecurrent = type;
35 void PR_MoveParms(progfuncs_t *progfuncs, progsnum_t progs1, progsnum_t progs2) //from 2 to 1
42 return; //don't bother coping variables to themselves...
44 p1 = &pr_progstate[(int)progs1];
45 p2 = &pr_progstate[(int)progs2];
47 if ((unsigned)progs1 >= maxprogs || !p1->globals)
48 Sys_Error("QCLIB: Bad prog type - %i", progs1);
49 if ((unsigned)progs2 >= maxprogs || !p2->globals)
50 Sys_Error("QCLIB: Bad prog type - %i", progs2);
53 for (a = 0; a < MAX_PARMS;a++)
55 *(int *)&p1->globals[OFS_PARM0+3*a ] = *(int *)&p2->globals[OFS_PARM0+3*a ];
56 *(int *)&p1->globals[OFS_PARM0+3*a+1] = *(int *)&p2->globals[OFS_PARM0+3*a+1];
57 *(int *)&p1->globals[OFS_PARM0+3*a+2] = *(int *)&p2->globals[OFS_PARM0+3*a+2];
59 p1->globals[OFS_RETURN] = p2->globals[OFS_RETURN];
60 p1->globals[OFS_RETURN+1] = p2->globals[OFS_RETURN+1];
61 p1->globals[OFS_RETURN+2] = p2->globals[OFS_RETURN+2];
63 //move the vars defined as shared.
64 for (a = 0; a < numshares; a++)//fixme: make offset per progs
66 memmove(&((int *)p1->globals)[shares[a].varofs], &((int *)p2->globals)[shares[a].varofs], shares[a].size*4);
67 /* ((int *)p1->globals)[shares[a].varofs] = ((int *)p2->globals)[shares[a].varofs];
68 if (shares[a].size > 1)
70 ((int *)p1->globals)[shares[a].varofs+1] = ((int *)p2->globals)[shares[a].varofs+1];
71 if (shares[a].size > 2)
72 ((int *)p1->globals)[shares[a].varofs+2] = ((int *)p2->globals)[shares[a].varofs+2];
78 progsnum_t PR_LoadProgs(progfuncs_t *progfuncs, char *s, int headercrc, builtin_t *builtins, int numbuiltins)
82 oldtype = pr_typecurrent;
83 for (a = 0; a < maxprogs; a++)
85 if (pr_progstate[a].progs == NULL)
88 current_progstate = &pr_progstate[a];
89 if (PR_ReallyLoadProgs(progfuncs, s, headercrc, &pr_progstate[a], false)) //try and load it
91 current_progstate->builtins = builtins;
92 current_progstate->numbuiltins = numbuiltins;
96 prinst->usejit = PR_GenerateJit(progfuncs);
99 PR_SwitchProgs(progfuncs, oldtype);
100 return a; //we could load it. Yay!
103 PR_SwitchProgs(progfuncs, oldtype);
104 return -1; // loading failed.
107 PR_SwitchProgs(progfuncs, oldtype);
111 void PR_ShiftParms(progfuncs_t *progfuncs, int amount)
114 for (a = 0; a < MAX_PARMS - amount;a++)
115 *(int *)&pr_globals[OFS_PARM0+3*a] = *(int *)&pr_globals[OFS_PARM0+3*(amount+a)];
119 void PR_Clear(progfuncs_t *progfuncs)
122 for (a = 0; a < maxprogs; a++)
124 pr_progstate[a].progs = NULL;
130 void QC_StartShares(progfuncs_t *progfuncs)
136 shares = memalloc(sizeof(sharedvar_t)*maxshares);
138 void QC_AddSharedVar(progfuncs_t *progfuncs, int start, int size) //fixme: make offset per progs and optional
143 if (numshares >= maxshares)
148 shares = memalloc(sizeof(sharedvar_t)*maxshares);
150 memcpy(shares, buf, sizeof(sharedvar_t)*numshares);
155 for (a = 0; a < numshares; a++)
157 if (shares[a].varofs+shares[a].size == ofs)
159 shares[a].size += size; //expand size.
162 if (shares[a].varofs == start)
167 shares[numshares].varofs = start;
168 shares[numshares].size = size;
173 //void ShowWatch(void);
175 void QC_InitShares(progfuncs_t *progfuncs)
178 if (!field) //don't make it so we will just need to remalloc everything
181 field = memalloc(sizeof(fdef_t) * maxfields);
185 progfuncs->fieldadjust = 0;
188 void QC_FlushProgsOffsets(progfuncs_t *progfuncs)
189 { //sets the fields up for loading a new progs.
190 //fields are matched by name to other progs
193 for (i = 0; i < numfields; i++)
194 field[i].progsofs = -1;
198 //called if a global is defined as a field
201 //vectors must be added before any of their corresponding _x/y/z vars
202 //in this way, even screwed up progs work.
204 //requestedpos is the offset the engine WILL put it at.
205 //origionaloffs is used to track matching field offsets. fields with the same progs offset overlap
207 //note: we probably suffer from progs with renamed system globals.
208 int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, int engineofs, int progsofs)
218 if (!name) //engine can use this to offset all progs fields
219 { //which fixes constant field offsets (some ktpro arrays)
220 progfuncs->fieldadjust = fields_size/4;
225 prinst->reorganisefields = true;
227 //look for an existing match
228 for (i = 0; i < numfields; i++)
230 if (!strcmp(name, field[i].name))
232 if (field[i].type != type)
234 printf("Field type mismatch on \"%s\"\n", name);
237 if (!progfuncs->fieldadjust && engineofs>=0)
238 if ((unsigned)engineofs/4 != field[i].ofs)
239 Sys_Error("Field %s at wrong offset", name);
241 if (field[i].progsofs == -1)
242 field[i].progsofs = progsofs;
243 // printf("Dupfield %s %i -> %i\n", name, field[i].progsofs,field[i].ofs);
244 return field[i].ofs-progfuncs->fieldadjust; //got a match
248 if (numfields+1>maxfields)
253 nf = memalloc(sizeof(fdef_t) * maxfields);
254 memcpy(nf, field, sizeof(fdef_t) * i);
259 //try to add a new one
262 field[fnum].name = name;
263 if (type == ev_vector)
266 namelen = strlen(name)+5;
268 n=PRHunkAlloc(progfuncs, namelen);
269 sprintf(n, "%s_x", name);
270 ofs = QC_RegisterFieldVar(progfuncs, ev_float, n, engineofs, progsofs);
271 field[fnum].ofs = ofs+progfuncs->fieldadjust;
273 n=PRHunkAlloc(progfuncs, namelen);
274 sprintf(n, "%s_y", name);
275 QC_RegisterFieldVar(progfuncs, ev_float, n, (engineofs==-1)?-1:(engineofs+4), (progsofs==-1)?-1:progsofs+1);
277 n=PRHunkAlloc(progfuncs, namelen);
278 sprintf(n, "%s_z", name);
279 QC_RegisterFieldVar(progfuncs, ev_float, n, (engineofs==-1)?-1:(engineofs+8), (progsofs==-1)?-1:progsofs+2);
281 else if (engineofs >= 0)
282 { //the engine is setting up a list of required field indexes.
284 //paranoid checking of the offset.
285 /* for (i = 0; i < numfields-1; i++)
287 if (field[i].ofs == ((unsigned)engineofs)/4)
289 if (type == ev_float && field[i].type == ev_vector) //check names
291 if (strncmp(field[i].name, name, strlen(field[i].name)))
292 Sys_Error("Duplicated offset");
295 Sys_Error("Duplicated offset");
299 Sys_Error("field %s is %i&3", name, engineofs);
300 field[fnum].ofs = ofs = engineofs/4;
303 { //we just found a new fieldname inside a progs
304 field[fnum].ofs = ofs = fields_size/4; //add on the end
306 //if the progs field offset matches annother offset in the same progs, make it match up with the earlier one.
309 for (i = 0; i < numfields-1; i++)
311 if (field[i].progsofs == (unsigned)progsofs)
313 // printf("found union field %s %i -> %i\n", field[i].name, field[i].progsofs, field[i].ofs);
314 field[fnum].ofs = ofs = field[i].ofs;
320 // if (type != ev_vector)
321 if (fields_size < (ofs+type_size[type])*4)
322 fields_size = (ofs+type_size[type])*4;
324 if (max_fields_size && fields_size > max_fields_size)
325 Sys_Error("Allocated too many additional fields after ents were inited.");
326 field[fnum].type = type;
328 field[fnum].progsofs = progsofs;
330 // printf("Field %s %i -> %i\n", name, field[fnum].progsofs,field[fnum].ofs);
332 //we've finished setting the structure
333 return ofs - progfuncs->fieldadjust;
337 //called if a global is defined as a field
338 void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable)
346 //look for an existing match not needed, cos we look a little later too.
348 for (i = 0; i < numfields; i++)
350 if (!strcmp(pr_globaldefs[num].s_name, field[i].s_name))
352 //really we should look for a field def
354 *(int *)&pr_globals[pr_globaldefs[num].ofs] = field[i].ofs; //got a match
361 switch(current_progstate->intsize)
365 for (i=1 ; i<pr_progs->numfielddefs; i++)
367 if (!strcmp(pr_fielddefs16[i].s_name+stringtable, pr_globaldefs16[num].s_name+stringtable))
369 // int old = *(int *)&pr_globals[pr_globaldefs16[num].ofs];
370 *(int *)&pr_globals[pr_globaldefs16[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs16[i].type, pr_globaldefs16[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs16[num].ofs]);
372 // printf("Field %s %i -> %i\n", pr_globaldefs16[num].s_name+stringtable, old, *(int *)&pr_globals[pr_globaldefs16[num].ofs]);
377 s = pr_globaldefs16[num].s_name+stringtable;
379 for (i = 0; i < numfields; i++)
381 o = field[i].progsofs;
382 if (o == *(unsigned int *)&pr_globals[pr_globaldefs16[num].ofs])
384 // int old = *(int *)&pr_globals[pr_globaldefs16[num].ofs];
385 *(int *)&pr_globals[pr_globaldefs16[num].ofs] = field[i].ofs-progfuncs->fieldadjust;
386 // printf("Field %s %i -> %i\n", pr_globaldefs16[num].s_name+stringtable, old, *(int *)&pr_globals[pr_globaldefs16[num].ofs]);
391 //oh well, must be a parameter.
392 // if (*(int *)&pr_globals[pr_globaldefs16[num].ofs])
393 // Sys_Error("QCLIB: Global field var with no matching field \"%s\", from offset %i", pr_globaldefs16[num].s_name+stringtable, *(int *)&pr_globals[pr_globaldefs16[num].ofs]);
396 for (i=1 ; i<pr_progs->numfielddefs; i++)
398 if (!strcmp(pr_fielddefs32[i].s_name+stringtable, pr_globaldefs32[num].s_name+stringtable))
400 *(int *)&pr_globals[pr_globaldefs32[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs32[i].type, pr_globaldefs32[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs32[num].ofs]);
405 s = pr_globaldefs32[num].s_name+stringtable;
407 for (i = 0; i < numfields; i++)
409 o = field[i].progsofs;
410 if (o == *(unsigned int *)&pr_globals[pr_globaldefs32[num].ofs])
412 *(int *)&pr_globals[pr_globaldefs32[num].ofs] = field[i].ofs-progfuncs->fieldadjust;
417 //oh well, must be a parameter.
418 if (*(int *)&pr_globals[pr_globaldefs32[num].ofs])
419 Sys_Error("QCLIB: Global field var with no matching field \"%s\", from offset %i", pr_globaldefs32[num].s_name+stringtable, *(int *)&pr_globals[pr_globaldefs32[num].ofs]);
422 Sys_Error("Bad bits");
425 Sys_Error("Should be unreachable");