X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=prvm_cmds.c;h=f62583115eff0a82393ae8fb8da16d1738035109;hp=657e4b81914b5c3904b8ebaae6d1aee176da08ea;hb=add1a1b0abc10b8e720d74aeac52ad8276ee9fe0;hpb=b3c18f5f8496e077eb2d16077f4775b178f9b086 diff --git a/prvm_cmds.c b/prvm_cmds.c index 657e4b81..f6258311 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -17,6 +17,7 @@ #include "mdfour.h" extern cvar_t prvm_backtraceforwarnings; +extern dllhandle_t ode_dll; // LordHavoc: changed this to NOT use a return statement, so that it can be used in functions that must return a value void VM_Warning(prvm_prog_t *prog, const char *fmt, ...) @@ -84,7 +85,7 @@ void VM_GenerateFrameGroupBlend(prvm_prog_t *prog, framegroupblend_t *framegroup // LordHavoc: quite tempting to break apart this function to reuse the // duplicated code, but I suspect it is better for performance // this way -void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroupblend_t *framegroupblend, const dp_model_t *model) +void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroupblend_t *framegroupblend, const dp_model_t *model, double curtime) { int sub2, numframes, f, i, k; int isfirstframegroup = true; @@ -96,7 +97,7 @@ void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroup memset(blend, 0, MAX_FRAMEBLENDS * sizeof(*blend)); - if (!model || !model->surfmesh.isanimated || model->numframes <= 1) + if (!model || !model->surfmesh.isanimated) { blend[0].lerp = 1; return; @@ -133,7 +134,7 @@ void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroup if (scene->framecount > 1) { // this code path is only used on .zym models and torches - sublerp = scene->framerate * (cl.time - g->start); + sublerp = scene->framerate * (curtime - g->start); f = (int) floor(sublerp); sublerp -= f; sub2 = f + 1; @@ -277,10 +278,14 @@ static qboolean checkextension(prvm_prog_t *prog, const char *name) // special sheck for ODE if (!strncasecmp("DP_PHYSICS_ODE", name, 14)) { -#ifdef USEODE +#ifdef ODE_DYNAMIC return ode_dll ? true : false; +#else +#ifdef ODE_STATIC + return true; #else return false; +#endif #endif } @@ -450,7 +455,7 @@ vector normalize(vector) */ void VM_normalize(prvm_prog_t *prog) { - float *value1; + prvm_vec_t *value1; vec3_t newvalue; double f; @@ -492,8 +497,8 @@ float vectoyaw(vector) */ void VM_vectoyaw(prvm_prog_t *prog) { - float *value1; - float yaw; + prvm_vec_t *value1; + prvm_vec_t yaw; VM_SAFEPARMCOUNT(1,VM_vectoyaw); @@ -521,9 +526,18 @@ vector vectoangles(vector[, vector]) */ void VM_vectoangles(prvm_prog_t *prog) { + vec3_t result, forward, up; VM_SAFEPARMCOUNTRANGE(1, 2,VM_vectoangles); - AnglesFromVectors(PRVM_G_VECTOR(OFS_RETURN), PRVM_G_VECTOR(OFS_PARM0), prog->argc >= 2 ? PRVM_G_VECTOR(OFS_PARM1) : NULL, true); + VectorCopy(PRVM_G_VECTOR(OFS_PARM0), forward); + if (prog->argc >= 2) + { + VectorCopy(PRVM_G_VECTOR(OFS_PARM1), up); + AnglesFromVectors(result, forward, up, true); + } + else + AnglesFromVectors(result, forward, NULL, true); + VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN)); } /* @@ -2064,7 +2078,7 @@ void VM_getentityfieldstring(prvm_prog_t *prog) // put the data into a string ddef_t *d; int type, j; - int *v; + prvm_eval_t *val; prvm_edict_t * ent; int i = (int)PRVM_G_FLOAT(OFS_PARM0); char valuebuf[MAX_INPUTLINE]; @@ -2086,12 +2100,12 @@ void VM_getentityfieldstring(prvm_prog_t *prog) VM_Warning(prog, "VM_entityfielddata: %s: entity %i is free !\n", prog->name, PRVM_NUM_FOR_EDICT(ent)); return; } - v = (int *)((char *)ent->fields.vp + d->ofs*4); + val = (prvm_eval_t *)(ent->fields.fp + d->ofs); // if it's 0 or blank, return an empty string type = d->type & ~DEF_SAVEGLOBAL; for (j=0 ; jivector[j]) break; if (j == prvm_type_size[type]) { @@ -2099,7 +2113,7 @@ void VM_getentityfieldstring(prvm_prog_t *prog) return; } - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, PRVM_UglyValueString(prog, (etype_t)d->type, (prvm_eval_t *)v, valuebuf, sizeof(valuebuf))); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, PRVM_UglyValueString(prog, (etype_t)d->type, val, valuebuf, sizeof(valuebuf))); } // KrimZon - DP_QC_ENTITYDATA @@ -3241,18 +3255,34 @@ VM_precache_pic string precache_pic(string pic) ========= */ +#define PRECACHE_PIC_FROMWAD 1 /* FTEQW, not supported here */ +#define PRECACHE_PIC_NOTPERSISTENT 2 +//#define PRECACHE_PIC_NOCLAMP 4 +#define PRECACHE_PIC_MIPMAP 8 void VM_precache_pic(prvm_prog_t *prog) { const char *s; + int flags = 0; - VM_SAFEPARMCOUNT(1, VM_precache_pic); + VM_SAFEPARMCOUNTRANGE(1, 2, VM_precache_pic); s = PRVM_G_STRING(OFS_PARM0); PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0); VM_CheckEmptyString(prog, s); + if(prog->argc >= 2) + { + int f = PRVM_G_FLOAT(OFS_PARM1); + if(f & PRECACHE_PIC_NOTPERSISTENT) + flags |= CACHEPICFLAG_NOTPERSISTENT; + //if(f & PRECACHE_PIC_NOCLAMP) + // flags |= CACHEPICFLAG_NOCLAMP; + if(f & PRECACHE_PIC_MIPMAP) + flags |= CACHEPICFLAG_MIPMAP; + } + // AK Draw_CachePic is supposed to always return a valid pointer - if( Draw_CachePic_Flags(s, 0)->tex == r_texture_notexture ) + if( Draw_CachePic_Flags(s, flags)->tex == r_texture_notexture ) PRVM_G_INT(OFS_RETURN) = OFS_NULL; } @@ -3304,7 +3334,7 @@ float drawcharacter(vector position, float character, vector scale, vector rgb, */ void VM_drawcharacter(prvm_prog_t *prog) { - float *pos,*scale,*rgb; + prvm_vec_t *pos,*scale,*rgb; char character; int flag; float sx, sy; @@ -3354,7 +3384,7 @@ float drawstring(vector position, string text, vector scale, vector rgb, float a */ void VM_drawstring(prvm_prog_t *prog) { - float *pos,*scale,*rgb; + prvm_vec_t *pos,*scale,*rgb; const char *string; int flag = 0; float sx, sy; @@ -3401,7 +3431,7 @@ float drawcolorcodedstring(vector position, string text, vector scale, vector rg */ void VM_drawcolorcodedstring(prvm_prog_t *prog) { - float *pos, *scale; + prvm_vec_t *pos, *scale; const char *string; int flag; vec3_t rgb; @@ -3464,7 +3494,7 @@ float stringwidth(string text, float allowColorCodes, float size) void VM_stringwidth(prvm_prog_t *prog) { const char *string; - float *szv; + vec2_t szv; float mult; // sz is intended font size so we can later add freetype support, mult is font size multiplier in pixels per character cell int colors; float sx, sy; @@ -3474,14 +3504,13 @@ void VM_stringwidth(prvm_prog_t *prog) getdrawfontscale(prog, &sx, &sy); if(prog->argc == 3) { - szv = PRVM_G_VECTOR(OFS_PARM2); + Vector2Copy(PRVM_G_VECTOR(OFS_PARM2), szv); mult = 1; } else { // we want the width for 8x8 font size, divided by 8 - static float defsize[] = {8, 8}; - szv = defsize; + Vector2Set(szv, 8, 8); mult = 0.125; // to make sure snapping is turned off, ALWAYS use a nontrivial scale in this case if(sx >= 0.9 && sx <= 1.1) @@ -3690,7 +3719,7 @@ float drawpic(vector position, string pic, vector size, vector rgb, float alpha, void VM_drawpic(prvm_prog_t *prog) { const char *picname; - float *size, *pos, *rgb; + prvm_vec_t *size, *pos, *rgb; int flag = 0; VM_SAFEPARMCOUNTRANGE(5,6,VM_drawpic); @@ -3735,7 +3764,7 @@ float drawrotpic(vector position, string pic, vector size, vector org, float ang void VM_drawrotpic(prvm_prog_t *prog) { const char *picname; - float *size, *pos, *org, *rgb; + prvm_vec_t *size, *pos, *org, *rgb; int flag; VM_SAFEPARMCOUNT(8,VM_drawrotpic); @@ -3781,7 +3810,7 @@ float drawsubpic(vector position, vector size, string pic, vector srcPos, vector void VM_drawsubpic(prvm_prog_t *prog) { const char *picname; - float *size, *pos, *rgb, *srcPos, *srcSize, alpha; + prvm_vec_t *size, *pos, *rgb, *srcPos, *srcSize, alpha; int flag; VM_SAFEPARMCOUNT(8,VM_drawsubpic); @@ -3834,7 +3863,7 @@ float drawfill(vector position, vector size, vector rgb, float alpha, float flag */ void VM_drawfill(prvm_prog_t *prog) { - float *size, *pos, *rgb; + prvm_vec_t *size, *pos, *rgb; int flag; VM_SAFEPARMCOUNT(5,VM_drawfill); @@ -3911,9 +3940,16 @@ void VM_getimagesize(prvm_prog_t *prog) VM_CheckEmptyString(prog, p); pic = Draw_CachePic_Flags (p, CACHEPICFLAG_NOTPERSISTENT); - - PRVM_G_VECTOR(OFS_RETURN)[0] = pic->width; - PRVM_G_VECTOR(OFS_RETURN)[1] = pic->height; + if( pic->tex == r_texture_notexture ) + { + PRVM_G_VECTOR(OFS_RETURN)[0] = 0; + PRVM_G_VECTOR(OFS_RETURN)[1] = 0; + } + else + { + PRVM_G_VECTOR(OFS_RETURN)[0] = pic->width; + PRVM_G_VECTOR(OFS_RETURN)[1] = pic->height; + } PRVM_G_VECTOR(OFS_RETURN)[2] = 0; } @@ -4270,8 +4306,13 @@ void makevectors(vector angle) */ void VM_makevectors (prvm_prog_t *prog) { + vec3_t angles, forward, right, up; VM_SAFEPARMCOUNT(1, VM_makevectors); - AngleVectors(PRVM_G_VECTOR(OFS_PARM0), PRVM_gameglobalvector(v_forward), PRVM_gameglobalvector(v_right), PRVM_gameglobalvector(v_up)); + VectorCopy(PRVM_G_VECTOR(OFS_PARM0), angles); + AngleVectors(angles, forward, right, up); + VectorCopy(forward, PRVM_gameglobalvector(v_forward)); + VectorCopy(right, PRVM_gameglobalvector(v_right)); + VectorCopy(up, PRVM_gameglobalvector(v_up)); } /* @@ -4284,9 +4325,13 @@ vectorvectors(vector) */ void VM_vectorvectors (prvm_prog_t *prog) { + vec3_t forward, right, up; VM_SAFEPARMCOUNT(1, VM_vectorvectors); - VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), PRVM_gameglobalvector(v_forward)); - VectorVectors(PRVM_gameglobalvector(v_forward), PRVM_gameglobalvector(v_right), PRVM_gameglobalvector(v_up)); + VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), forward); + VectorVectors(forward, right, up); + VectorCopy(forward, PRVM_gameglobalvector(v_forward)); + VectorCopy(right, PRVM_gameglobalvector(v_right)); + VectorCopy(up, PRVM_gameglobalvector(v_up)); } /* @@ -4298,7 +4343,7 @@ void drawline(float width, vector pos1, vector pos2, vector rgb, float alpha, fl */ void VM_drawline (prvm_prog_t *prog) { - float *c1, *c2, *rgb; + prvm_vec_t *c1, *c2, *rgb; float alpha, width; unsigned char flags; @@ -4599,7 +4644,7 @@ void VM_buf_create (prvm_prog_t *prog) int i; VM_SAFEPARMCOUNTRANGE(0, 2, VM_buf_create); - + // VorteX: optional parm1 (buffer format) is unfinished, to keep intact with future databuffers extension must be set to "string" if(prog->argc >= 1 && strcmp(PRVM_G_STRING(OFS_PARM0), "string")) { @@ -4963,11 +5008,358 @@ void VM_bufstr_free (prvm_prog_t *prog) BufStr_Shrink(prog, stringbuffer); } +/* +======================== +VM_buf_loadfile +load a file into string buffer, return 0 or 1 +float buf_loadfile(string filename, float bufhandle) = #535; +======================== +*/ +void VM_buf_loadfile(prvm_prog_t *prog) +{ + size_t alloclen; + prvm_stringbuffer_t *stringbuffer; + char string[VM_STRINGTEMP_LENGTH]; + int filenum, strindex, c, end; + const char *filename; + char vabuf[1024]; + VM_SAFEPARMCOUNT(2, VM_buf_loadfile); + // get file + filename = PRVM_G_STRING(OFS_PARM0); + for (filenum = 0;filenum < PRVM_MAX_OPENFILES;filenum++) + if (prog->openfiles[filenum] == NULL) + break; + prog->openfiles[filenum] = FS_OpenVirtualFile(va(vabuf, sizeof(vabuf), "data/%s", filename), false); + if (prog->openfiles[filenum] == NULL) + prog->openfiles[filenum] = FS_OpenVirtualFile(va(vabuf, sizeof(vabuf), "%s", filename), false); + if (prog->openfiles[filenum] == NULL) + { + if (developer_extra.integer) + VM_Warning(prog, "VM_buf_loadfile: failed to open file %s in %s\n", filename, prog->name); + PRVM_G_FLOAT(OFS_RETURN) = 0; + return; + } + // get string buffer + stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM1)); + if(!stringbuffer) + { + VM_Warning(prog, "VM_buf_loadfile: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM1), prog->name); + PRVM_G_FLOAT(OFS_RETURN) = 0; + return; + } + // read file (append to the end of buffer) + strindex = stringbuffer->num_strings; + while(1) + { + // read line + end = 0; + for (;;) + { + c = FS_Getc(prog->openfiles[filenum]); + if (c == '\r' || c == '\n' || c < 0) + break; + if (end < VM_STRINGTEMP_LENGTH - 1) + string[end++] = c; + } + string[end] = 0; + // remove \n following \r + if (c == '\r') + { + c = FS_Getc(prog->openfiles[filenum]); + if (c != '\n') + FS_UnGetc(prog->openfiles[filenum], (unsigned char)c); + } + // add and continue + if (c >= 0 || end) + { + BufStr_Expand(prog, stringbuffer, strindex); + stringbuffer->num_strings = max(stringbuffer->num_strings, strindex + 1); + alloclen = strlen(string) + 1; + stringbuffer->strings[strindex] = (char *)Mem_Alloc(prog->progs_mempool, alloclen); + memcpy(stringbuffer->strings[strindex], string, alloclen); + strindex = stringbuffer->num_strings; + } + else + break; + } + + // close file + FS_Close(prog->openfiles[filenum]); + prog->openfiles[filenum] = NULL; + if (prog->openfiles_origin[filenum]) + PRVM_Free((char *)prog->openfiles_origin[filenum]); + PRVM_G_FLOAT(OFS_RETURN) = 1; +} +/* +======================== +VM_buf_writefile +writes stringbuffer to a file, returns 0 or 1 +float buf_writefile(float filehandle, float bufhandle, [, float startpos, float numstrings]) = #468; +======================== +*/ + +void VM_buf_writefile(prvm_prog_t *prog) +{ + int filenum, strindex, strnum, strlength; + prvm_stringbuffer_t *stringbuffer; + + VM_SAFEPARMCOUNTRANGE(2, 4, VM_buf_writefile); + + // get file + filenum = (int)PRVM_G_FLOAT(OFS_PARM0); + if (filenum < 0 || filenum >= PRVM_MAX_OPENFILES) + { + VM_Warning(prog, "VM_buf_writefile: invalid file handle %i used in %s\n", filenum, prog->name); + return; + } + if (prog->openfiles[filenum] == NULL) + { + VM_Warning(prog, "VM_buf_writefile: no such file handle %i (or file has been closed) in %s\n", filenum, prog->name); + return; + } + + // get string buffer + stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM1)); + if(!stringbuffer) + { + VM_Warning(prog, "VM_buf_writefile: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM1), prog->name); + PRVM_G_FLOAT(OFS_RETURN) = 0; + return; + } + + // get start and end parms + if (prog->argc > 3) + { + strindex = (int)PRVM_G_FLOAT(OFS_PARM2); + strnum = (int)PRVM_G_FLOAT(OFS_PARM3); + } + else if (prog->argc > 2) + { + strindex = (int)PRVM_G_FLOAT(OFS_PARM2); + strnum = stringbuffer->num_strings - strindex; + } + else + { + strindex = 0; + strnum = stringbuffer->num_strings; + } + if (strindex < 0 || strindex >= stringbuffer->num_strings) + { + VM_Warning(prog, "VM_buf_writefile: wrong start string index %i used in %s\n", strindex, prog->name); + PRVM_G_FLOAT(OFS_RETURN) = 0; + return; + } + if (strnum < 0) + { + VM_Warning(prog, "VM_buf_writefile: wrong strings count %i used in %s\n", strnum, prog->name); + PRVM_G_FLOAT(OFS_RETURN) = 0; + return; + } + + // write + while(strindex < stringbuffer->num_strings && strnum) + { + if (stringbuffer->strings[strindex]) + { + if ((strlength = strlen(stringbuffer->strings[strindex]))) + FS_Write(prog->openfiles[filenum], stringbuffer->strings[strindex], strlength); + FS_Write(prog->openfiles[filenum], "\n", 1); + } + strindex++; + strnum--; + } + + PRVM_G_FLOAT(OFS_RETURN) = 1; +} + +#define MATCH_AUTO 0 +#define MATCH_WHOLE 1 +#define MATCH_LEFT 2 +#define MATCH_RIGHT 3 +#define MATCH_MIDDLE 4 +#define MATCH_PATTERN 5 + +static const char *detect_match_rule(char *pattern, int *matchrule) +{ + char *ppos, *qpos; + int patternlength; + + patternlength = strlen(pattern); + ppos = strchr(pattern, '*'); + qpos = strchr(pattern, '?'); + // has ? - pattern + if (qpos) + { + *matchrule = MATCH_PATTERN; + return pattern; + } + // has * - left, mid, right or pattern + if (ppos) + { + // starts with * - may be right/mid or pattern + if ((ppos - pattern) == 0) + { + ppos = strchr(pattern+1, '*'); + // *something + if (!ppos) + { + *matchrule = MATCH_RIGHT; + return pattern+1; + } + // *something* + if ((ppos - pattern) == patternlength) + { + *matchrule = MATCH_MIDDLE; + *ppos = 0; + return pattern+1; + } + // *som*thing + *matchrule = MATCH_PATTERN; + return pattern; + } + // end with * - left + if ((ppos - pattern) == patternlength) + { + *matchrule = MATCH_LEFT; + *ppos = 0; + return pattern; + } + // som*thing + *matchrule = MATCH_PATTERN; + return pattern; + } + // have no wildcards - whole string + *matchrule = MATCH_WHOLE; + return pattern; +} + +// todo: support UTF8 +static qboolean match_rule(const char *string, int max_string, const char *pattern, int patternlength, int rule) +{ + const char *mid; + + if (rule == 1) + return !strncmp(string, pattern, max_string) ? true : false; + if (rule == 2) + return !strncmp(string, pattern, patternlength) ? true : false; + if (rule == 3) + { + mid = strstr(string, pattern); + return mid && !*(mid+patternlength); + } + if (rule == 4) + return strstr(string, pattern) ? true : false; + // pattern + return matchpattern_with_separator(string, pattern, false, "", false) ? true : false; +} + +/* +======================== +VM_bufstr_find +find an index of bufstring matching rule +float bufstr_find(float bufhandle, string match, float matchrule, float startpos, float step) = #468; +======================== +*/ + +void VM_bufstr_find(prvm_prog_t *prog) +{ + prvm_stringbuffer_t *stringbuffer; + char string[VM_STRINGTEMP_LENGTH]; + int matchrule, matchlen, i, step; + const char *match; + + VM_SAFEPARMCOUNTRANGE(3, 5, VM_bufstr_find); + + PRVM_G_FLOAT(OFS_RETURN) = -1; + + // get string buffer + stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0)); + if(!stringbuffer) + { + VM_Warning(prog, "VM_bufstr_find: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name); + return; + } + + // get pattern/rule + matchrule = (int)PRVM_G_FLOAT(OFS_PARM2); + if (matchrule < 0 && matchrule > 5) + { + VM_Warning(prog, "VM_bufstr_find: invalid match rule %i in %s\n", matchrule, prog->name); + return; + } + if (matchrule) + match = PRVM_G_STRING(OFS_PARM1); + else + { + strlcpy(string, PRVM_G_STRING(OFS_PARM1), sizeof(string)); + match = detect_match_rule(string, &matchrule); + } + matchlen = strlen(match); + + // find + i = (prog->argc > 3) ? (int)PRVM_G_FLOAT(OFS_PARM3) : 0; + step = (prog->argc > 4) ? (int)PRVM_G_FLOAT(OFS_PARM4) : 1; + while(i < stringbuffer->num_strings) + { + if (stringbuffer->strings[i] && match_rule(stringbuffer->strings[i], VM_STRINGTEMP_LENGTH, match, matchlen, matchrule)) + { + PRVM_G_FLOAT(OFS_RETURN) = i; + break; + } + i += step; + } +} + +/* +======================== +VM_matchpattern +float matchpattern(string s, string pattern, float matchrule, float startpos) = #468; +======================== +*/ +void VM_matchpattern(prvm_prog_t *prog) +{ + const char *s, *match; + char string[VM_STRINGTEMP_LENGTH]; + int matchrule, l; + + VM_SAFEPARMCOUNTRANGE(2, 4, VM_matchpattern); + + s = PRVM_G_STRING(OFS_PARM0); + + // get pattern/rule + matchrule = (int)PRVM_G_FLOAT(OFS_PARM2); + if (matchrule < 0 && matchrule > 5) + { + VM_Warning(prog, "VM_bufstr_find: invalid match rule %i in %s\n", matchrule, prog->name); + return; + } + if (matchrule) + match = PRVM_G_STRING(OFS_PARM1); + else + { + strlcpy(string, PRVM_G_STRING(OFS_PARM1), sizeof(string)); + match = detect_match_rule(string, &matchrule); + } + + // offset + l = strlen(match); + if (prog->argc > 3) + s += max(0, min((unsigned int)PRVM_G_FLOAT(OFS_PARM3), strlen(s)-1)); + + // match + PRVM_G_FLOAT(OFS_RETURN) = match_rule(s, VM_STRINGTEMP_LENGTH, match, l, matchrule); +} + +/* +======================== +VM_buf_cvarlist +======================== +*/ void VM_buf_cvarlist(prvm_prog_t *prog) { @@ -5873,7 +6265,7 @@ out1: out2: handle->postdata = NULL; handle->postlen = 0; - ret = Curl_Begin_ToMemory(url, 0, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle); + ret = Curl_Begin_ToMemory_POST(url, handle->sigdata, 0, NULL, NULL, 0, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle); } if(ret) { @@ -6046,8 +6438,8 @@ void VM_sprintf(prvm_prog_t *prog) char formatbuf[16]; char *f; int isfloat; - static int dummyivec[3] = {0, 0, 0}; - static float dummyvec[3] = {0, 0, 0}; + static prvm_int_t dummyivec[3] = {0, 0, 0}; + static prvm_vec_t dummyvec[3] = {0, 0, 0}; char vabuf[1024]; #define PRINTF_ALTERNATE 1 @@ -6063,7 +6455,7 @@ void VM_sprintf(prvm_prog_t *prog) #define GETARG_FLOAT(a) (((a)>=1 && (a)argc) ? (PRVM_G_FLOAT(OFS_PARM0 + 3 * (a))) : 0) #define GETARG_VECTOR(a) (((a)>=1 && (a)argc) ? (PRVM_G_VECTOR(OFS_PARM0 + 3 * (a))) : dummyvec) #define GETARG_INT(a) (((a)>=1 && (a)argc) ? (PRVM_G_INT(OFS_PARM0 + 3 * (a))) : 0) -#define GETARG_INTVECTOR(a) (((a)>=1 && (a)argc) ? ((int*) PRVM_G_VECTOR(OFS_PARM0 + 3 * (a))) : dummyivec) +#define GETARG_INTVECTOR(a) (((a)>=1 && (a)argc) ? ((prvm_int_t*) PRVM_G_VECTOR(OFS_PARM0 + 3 * (a))) : dummyivec) #define GETARG_STRING(a) (((a)>=1 && (a)argc) ? (PRVM_G_STRING(OFS_PARM0 + 3 * (a))) : "") for(;;) @@ -6326,7 +6718,10 @@ nolength: { if(precision < 0) // not set precision = end - o - 1; - o += u8_strpad(o, end - o, GETARG_STRING(thisarg), (flags & PRINTF_LEFT) != 0, width, precision); + if(flags & PRINTF_SIGNPOSITIVE) + o += u8_strpad(o, end - o, GETARG_STRING(thisarg), (flags & PRINTF_LEFT) != 0, width, precision); + else + o += u8_strpad_colorcodes(o, end - o, GETARG_STRING(thisarg), (flags & PRINTF_LEFT) != 0, width, precision); } break; default: @@ -6398,7 +6793,7 @@ static void animatemodel(prvm_prog_t *prog, dp_model_t *model, prvm_edict_t *ed) memset(&animatemodel_cache, 0, sizeof(animatemodel_cache)); need |= (animatemodel_cache.model != model); VM_GenerateFrameGroupBlend(prog, ed->priv.server->framegroupblend, ed); - VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model); + VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model, PRVM_serverglobalfloat(time)); need |= (memcmp(&animatemodel_cache.frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend))) != 0; skeletonindex = (int)PRVM_gameedictfloat(ed, skeletonindex) - 1; if (!(skeletonindex >= 0 && skeletonindex < MAX_EDICTS && (skeleton = prog->skeletons[skeletonindex]) && skeleton->model->num_bones == ed->priv.server->skeleton.model->num_bones)) @@ -6543,6 +6938,7 @@ void VM_getsurfacepoint(prvm_prog_t *prog) dp_model_t *model; msurface_t *surface; int pointnum; + vec3_t result; VM_SAFEPARMCOUNT(3, VM_getsurfacepoint); VectorClear(PRVM_G_VECTOR(OFS_RETURN)); ed = PRVM_G_EDICT(OFS_PARM0); @@ -6553,7 +6949,8 @@ void VM_getsurfacepoint(prvm_prog_t *prog) if (pointnum < 0 || pointnum >= surface->num_vertices) return; animatemodel(prog, model, ed); - applytransform_forward(prog, &(animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN)); + applytransform_forward(prog, &(animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result); + VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN)); } //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486; // float SPA_POSITION = 0; @@ -6570,6 +6967,7 @@ void VM_getsurfacepointattribute(prvm_prog_t *prog) msurface_t *surface; int pointnum; int attributetype; + vec3_t result; VM_SAFEPARMCOUNT(4, VM_getsurfacepoint); VectorClear(PRVM_G_VECTOR(OFS_RETURN)); @@ -6586,36 +6984,40 @@ void VM_getsurfacepointattribute(prvm_prog_t *prog) switch( attributetype ) { // float SPA_POSITION = 0; case 0: - applytransform_forward(prog, &(animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN)); + applytransform_forward(prog, &(animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result); + VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN)); break; // float SPA_S_AXIS = 1; case 1: - applytransform_forward_direction(prog, &(animatemodel_cache.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN)); + applytransform_forward_direction(prog, &(animatemodel_cache.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result); + VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN)); break; // float SPA_T_AXIS = 2; case 2: - applytransform_forward_direction(prog, &(animatemodel_cache.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN)); + applytransform_forward_direction(prog, &(animatemodel_cache.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result); + VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN)); break; // float SPA_R_AXIS = 3; // same as SPA_NORMAL case 3: - applytransform_forward_direction(prog, &(animatemodel_cache.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, PRVM_G_VECTOR(OFS_RETURN)); + applytransform_forward_direction(prog, &(animatemodel_cache.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result); + VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN)); break; // float SPA_TEXCOORDS0 = 4; case 4: { - float *ret = PRVM_G_VECTOR(OFS_RETURN); float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2]; - ret[0] = texcoord[0]; - ret[1] = texcoord[1]; - ret[2] = 0.0f; + result[0] = texcoord[0]; + result[1] = texcoord[1]; + result[2] = 0.0f; + VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN)); break; } // float SPA_LIGHTMAP0_TEXCOORDS = 5; case 5: { - float *ret = PRVM_G_VECTOR(OFS_RETURN); float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2]; - ret[0] = texcoord[0]; - ret[1] = texcoord[1]; - ret[2] = 0.0f; + result[0] = texcoord[0]; + result[1] = texcoord[1]; + result[2] = 0.0f; + VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN)); break; } // float SPA_LIGHTMAP0_COLOR = 6; @@ -6634,6 +7036,7 @@ void VM_getsurfacenormal(prvm_prog_t *prog) dp_model_t *model; msurface_t *surface; vec3_t normal; + vec3_t result; VM_SAFEPARMCOUNT(2, VM_getsurfacenormal); VectorClear(PRVM_G_VECTOR(OFS_RETURN)); if (!(model = getmodel(prog, PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) @@ -6642,8 +7045,9 @@ void VM_getsurfacenormal(prvm_prog_t *prog) // well for curved surfaces or arbitrary meshes animatemodel(prog, model, PRVM_G_EDICT(OFS_PARM0)); TriangleNormal((animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex), (animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex) + 3, (animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex) + 6, normal); - applytransform_forward_normal(prog, normal, PRVM_G_EDICT(OFS_PARM0), PRVM_G_VECTOR(OFS_RETURN)); - VectorNormalize(PRVM_G_VECTOR(OFS_RETURN)); + applytransform_forward_normal(prog, normal, PRVM_G_EDICT(OFS_PARM0), result); + VectorNormalize(result); + VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN)); } //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437; void VM_getsurfacetexture(prvm_prog_t *prog) @@ -6665,11 +7069,11 @@ void VM_getsurfacenearpoint(prvm_prog_t *prog) prvm_edict_t *ed; dp_model_t *model; msurface_t *surface; - vec_t *point; + vec3_t point; VM_SAFEPARMCOUNT(2, VM_getsurfacenearpoint); PRVM_G_FLOAT(OFS_RETURN) = -1; ed = PRVM_G_EDICT(OFS_PARM0); - point = PRVM_G_VECTOR(OFS_PARM1); + VectorCopy(PRVM_G_VECTOR(OFS_PARM1), point); if (!ed || ed->priv.server->free) return; @@ -6712,14 +7116,15 @@ void VM_getsurfaceclippedpoint(prvm_prog_t *prog) prvm_edict_t *ed; dp_model_t *model; msurface_t *surface; - vec3_t p, out; + vec3_t p, out, inp; VM_SAFEPARMCOUNT(3, VM_te_getsurfaceclippedpoint); VectorClear(PRVM_G_VECTOR(OFS_RETURN)); ed = PRVM_G_EDICT(OFS_PARM0); if (!(model = getmodel(prog, ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) return; animatemodel(prog, model, ed); - applytransform_inverted(prog, PRVM_G_VECTOR(OFS_PARM2), ed, p); + VectorCopy(PRVM_G_VECTOR(OFS_PARM2), inp); + applytransform_inverted(prog, inp, ed, p); clippointtosurface(prog, ed, model, surface, p, out); VectorAdd(out, PRVM_serveredictvector(ed, origin), PRVM_G_VECTOR(OFS_RETURN)); } @@ -6826,9 +7231,9 @@ void VM_physics_addforce(prvm_prog_t *prog) VM_Warning(prog, "VM_physics_addforce: entity is not MOVETYPE_PHYSICS!\n"); return; } - f.type = ODEFUNC_RELFORCEATPOS; + f.type = ODEFUNC_FORCE; VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f.v1); - VectorSubtract(PRVM_serveredictvector(ed, origin), PRVM_G_VECTOR(OFS_PARM2), f.v2); + VectorCopy(PRVM_G_VECTOR(OFS_PARM2), f.v2); VM_physics_ApplyCmd(ed, &f); } @@ -6852,7 +7257,7 @@ void VM_physics_addtorque(prvm_prog_t *prog) VM_Warning(prog, "VM_physics_addtorque: entity is not MOVETYPE_PHYSICS!\n"); return; } - f.type = ODEFUNC_RELTORQUE; + f.type = ODEFUNC_TORQUE; VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f.v1); VM_physics_ApplyCmd(ed, &f); }