X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=prvm_cmds.c;h=13672c5d8a815667ef6fb079224785bf64755d84;hp=bd6b426ac236425423aa60e2d494c201d206ae84;hb=0c48e2d6fb65f8305fcf381b9da0fc3ab4f19a58;hpb=00f0f92f5a3b0410e7ab8d6d88d96950c6c40aa8 diff --git a/prvm_cmds.c b/prvm_cmds.c index bd6b426a..13672c5d 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -187,9 +187,14 @@ void VM_UpdateEdictSkeleton(prvm_edict_t *ed, const dp_model_t *edmodel, const f VM_RemoveEdictSkeleton(ed); ed->priv.server->skeleton.model = edmodel; } - if (!ed->priv.server->skeleton.relativetransforms && ed->priv.server->skeleton.model && ed->priv.server->skeleton.model->num_bones) - ed->priv.server->skeleton.relativetransforms = Mem_Alloc(prog->progs_mempool, ed->priv.server->skeleton.model->num_bones * sizeof(matrix4x4_t)); - if (ed->priv.server->skeleton.relativetransforms) + if (!ed->priv.server->skeleton.model || !ed->priv.server->skeleton.model->num_bones) + { + if(ed->priv.server->skeleton.relativetransforms) + Mem_Free(ed->priv.server->skeleton.relativetransforms); + ed->priv.server->skeleton.relativetransforms = NULL; + return; + } + { int skeletonindex = -1; skeleton_t *skeleton; @@ -198,30 +203,15 @@ void VM_UpdateEdictSkeleton(prvm_edict_t *ed, const dp_model_t *edmodel, const f if (skeletonindex >= 0 && skeletonindex < MAX_EDICTS && (skeleton = prog->skeletons[skeletonindex]) && skeleton->model->num_bones == ed->priv.server->skeleton.model->num_bones) { // custom skeleton controlled by the game (FTE_CSQC_SKELETONOBJECTS) + if (!ed->priv.server->skeleton.relativetransforms) + ed->priv.server->skeleton.relativetransforms = (matrix4x4_t *)Mem_Alloc(prog->progs_mempool, ed->priv.server->skeleton.model->num_bones * sizeof(matrix4x4_t)); memcpy(ed->priv.server->skeleton.relativetransforms, skeleton->relativetransforms, ed->priv.server->skeleton.model->num_bones * sizeof(matrix4x4_t)); } else { - // generated skeleton from frame animation - int blendindex; - int bonenum; - int numbones = ed->priv.server->skeleton.model->num_bones; - const short *framebones6s; - float lerp; - float scale = ed->priv.server->skeleton.model->num_posescale; - matrix4x4_t *relativetransforms = ed->priv.server->skeleton.relativetransforms; - matrix4x4_t matrix; - memset(relativetransforms, 0, numbones * sizeof(matrix4x4_t)); - for (blendindex = 0;blendindex < MAX_FRAMEBLENDS && frameblend[blendindex].lerp > 0;blendindex++) - { - lerp = frameblend[blendindex].lerp; - framebones6s = ed->priv.server->skeleton.model->data_poses6s + 6 * frameblend[blendindex].subframe * numbones; - for (bonenum = 0;bonenum < numbones;bonenum++) - { - Matrix4x4_FromBonePose6s(&matrix, scale, framebones6s + 6 * bonenum); - Matrix4x4_Accumulate(&ed->priv.server->skeleton.relativetransforms[bonenum], &matrix, lerp); - } - } + if(ed->priv.server->skeleton.relativetransforms) + Mem_Free(ed->priv.server->skeleton.relativetransforms); + ed->priv.server->skeleton.relativetransforms = NULL; } } } @@ -269,7 +259,7 @@ checkextension(extensionname) static qboolean checkextension(const char *name) { int len; - char *e, *start; + const char *e, *start; len = (int)strlen(name); for (e = prog->extensionstring;*e;e++) @@ -973,12 +963,12 @@ void VM_remove (void) ed = PRVM_G_EDICT(OFS_PARM0); if( PRVM_NUM_FOR_EDICT(ed) <= prog->reserved_edicts ) { - if (developer.integer) + if (developer.integer > 0) VM_Warning( "VM_remove: tried to remove the null entity or a reserved entity!\n" ); } else if( ed->priv.required->free ) { - if (developer.integer) + if (developer.integer > 0) VM_Warning( "VM_remove: tried to remove an already freed entity!\n" ); } else @@ -2878,6 +2868,50 @@ void VM_gettime(void) } } +/* +========= +VM_getsoundtime + +float getsoundtime(void) +========= +*/ + +void VM_getsoundtime (void) +{ + int entnum, entchannel, pnum; + VM_SAFEPARMCOUNT(2,VM_getsoundtime); + + pnum = PRVM_GetProgNr(); + if (pnum == PRVM_MENUPROG) + { + VM_Warning("VM_getsoundtime: %s: not supported on this progs\n", PRVM_NAME); + PRVM_G_FLOAT(OFS_RETURN) = -1; + return; + } + entnum = ((pnum == PRVM_CLIENTPROG) ? MAX_EDICTS : 0) + PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)); + entchannel = (int)PRVM_G_FLOAT(OFS_PARM1); + if (entchannel <= 0 || entchannel > 8) + VM_Warning("VM_getsoundtime: %s: bad channel %i\n", PRVM_NAME, entchannel); + PRVM_G_FLOAT(OFS_RETURN) = (float)S_GetEntChannelPosition(entnum, entchannel); +} + +/* +========= +VM_GetSoundLen + +string soundlength (string sample) +========= +*/ +void VM_soundlength (void) +{ + const char *s; + + VM_SAFEPARMCOUNT(1, VM_soundlength); + + s = PRVM_G_STRING(OFS_PARM0); + PRVM_G_FLOAT(OFS_RETURN) = S_SoundLength(s); +} + /* ========= VM_loadfromdata @@ -3190,7 +3224,7 @@ void VM_precache_pic(void) VM_CheckEmptyString (s); // AK Draw_CachePic is supposed to always return a valid pointer - if( Draw_CachePic_Flags(s, CACHEPICFLAG_NOTPERSISTENT)->tex == r_texture_notexture ) + if( Draw_CachePic_Flags(s, 0)->tex == r_texture_notexture ) PRVM_G_INT(OFS_RETURN) = OFS_NULL; } @@ -3233,9 +3267,9 @@ dp_font_t *getdrawfont(void) if(prog->globaloffsets.drawfont >= 0) { int f = (int) PRVM_G_FLOAT(prog->globaloffsets.drawfont); - if(f < 0 || f >= MAX_FONTS) + if(f < 0 || f >= dp_fonts.maxsize) return FONT_DEFAULT; - return &dp_fonts[f]; + return &dp_fonts.f[f]; } else return FONT_DEFAULT; @@ -3434,8 +3468,176 @@ void VM_stringwidth(void) PRVM_G_FLOAT(OFS_RETURN) = DrawQ_TextWidth(string, 0, !colors, getdrawfont()) * mult; // 1x1 characters, don't actually draw */ +} + +/* +========= +VM_findfont +float findfont(string s) +========= +*/ + +float getdrawfontnum(const char *fontname) +{ + int i; + + for(i = 0; i < dp_fonts.maxsize; ++i) + if(!strcmp(dp_fonts.f[i].title, fontname)) + return i; + return -1; +} + +void VM_findfont(void) +{ + VM_SAFEPARMCOUNT(1,VM_findfont); + PRVM_G_FLOAT(OFS_RETURN) = getdrawfontnum(PRVM_G_STRING(OFS_PARM0)); } + +/* +========= +VM_loadfont + +float loadfont(string fontname, string fontmaps, string sizes, float slot) +========= +*/ + +dp_font_t *FindFont(const char *title, qboolean allocate_new); +void LoadFont(qboolean override, const char *name, dp_font_t *fnt, float scale, float voffset); +void VM_loadfont(void) +{ + const char *fontname, *filelist, *sizes, *c, *cm; + char mainfont[MAX_QPATH]; + int i, numsizes; + float sz, scale, voffset; + dp_font_t *f; + + VM_SAFEPARMCOUNTRANGE(3,6,VM_loadfont); + + fontname = PRVM_G_STRING(OFS_PARM0); + if (!fontname[0]) + fontname = "default"; + + filelist = PRVM_G_STRING(OFS_PARM1); + if (!filelist[0]) + filelist = "gfx/conchars"; + + sizes = PRVM_G_STRING(OFS_PARM2); + if (!sizes[0]) + sizes = "10"; + + // find a font + f = NULL; + if (prog->argc >= 4) + { + i = PRVM_G_FLOAT(OFS_PARM3); + if (i >= 0 && i < dp_fonts.maxsize) + { + f = &dp_fonts.f[i]; + strlcpy(f->title, fontname, sizeof(f->title)); // replace name + } + } + if (!f) + f = FindFont(fontname, true); + if (!f) + { + PRVM_G_FLOAT(OFS_RETURN) = -1; + return; // something go wrong + } + + memset(f->fallbacks, 0, sizeof(f->fallbacks)); + memset(f->fallback_faces, 0, sizeof(f->fallback_faces)); + + // first font is handled "normally" + c = strchr(filelist, ':'); + cm = strchr(filelist, ','); + if(c && (!cm || c < cm)) + f->req_face = atoi(c+1); + else + { + f->req_face = 0; + c = cm; + } + if(!c || (c - filelist) > MAX_QPATH) + strlcpy(mainfont, filelist, sizeof(mainfont)); + else + { + memcpy(mainfont, filelist, c - filelist); + mainfont[c - filelist] = 0; + } + + // handle fallbacks + for(i = 0; i < MAX_FONT_FALLBACKS; ++i) + { + c = strchr(filelist, ','); + if(!c) + break; + filelist = c + 1; + if(!*filelist) + break; + c = strchr(filelist, ':'); + cm = strchr(filelist, ','); + if(c && (!cm || c < cm)) + f->fallback_faces[i] = atoi(c+1); + else + { + f->fallback_faces[i] = 0; // f->req_face; could make it stick to the default-font's face index + c = cm; + } + if(!c || (c-filelist) > MAX_QPATH) + { + strlcpy(f->fallbacks[i], filelist, sizeof(mainfont)); + } + else + { + memcpy(f->fallbacks[i], filelist, c - filelist); + f->fallbacks[i][c - filelist] = 0; + } + } + + // handle sizes + for(i = 0; i < MAX_FONT_SIZES; ++i) + f->req_sizes[i] = -1; + for (numsizes = 0,c = sizes;;) + { + if (!COM_ParseToken_VM_Tokenize(&c, 0)) + break; + sz = atof(com_token); + // detect crap size + if (sz < 0.001f || sz > 1000.0f) + { + VM_Warning("VM_loadfont: crap size %s", com_token); + continue; + } + // check overflow + if (numsizes == MAX_FONT_SIZES) + { + VM_Warning("VM_loadfont: MAX_FONT_SIZES = %i exceeded", MAX_FONT_SIZES); + break; + } + f->req_sizes[numsizes] = sz; + numsizes++; + } + + // additional scale/hoffset parms + scale = 1; + voffset = 0; + if (prog->argc >= 5) + { + scale = PRVM_G_FLOAT(OFS_PARM4); + if (scale <= 0) + scale = 1; + } + if (prog->argc >= 6) + voffset = PRVM_G_FLOAT(OFS_PARM5); + + // load + LoadFont(true, mainfont, f, scale, voffset); + + // return index of loaded font + PRVM_G_FLOAT(OFS_RETURN) = (f - dp_fonts.f); +} + /* ========= VM_drawpic @@ -3477,7 +3679,7 @@ void VM_drawpic(void) if(pos[2] || size[2]) Con_Printf("VM_drawpic: z value%s from %s discarded\n",(pos[2] && size[2]) ? "s" : " ",((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); - DrawQ_Pic(pos[0], pos[1], Draw_CachePic (picname), size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag); + DrawQ_Pic(pos[0], pos[1], Draw_CachePic_Flags (picname, CACHEPICFLAG_NOTPERSISTENT), size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag); PRVM_G_FLOAT(OFS_RETURN) = 1; } /* @@ -3522,7 +3724,7 @@ void VM_drawrotpic(void) if(pos[2] || size[2] || org[2]) Con_Printf("VM_drawrotpic: z value from pos/size/org discarded\n"); - DrawQ_RotPic(pos[0], pos[1], Draw_CachePic(picname), size[0], size[1], org[0], org[1], PRVM_G_FLOAT(OFS_PARM4), rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM6), flag); + DrawQ_RotPic(pos[0], pos[1], Draw_CachePic_Flags(picname, CACHEPICFLAG_NOTPERSISTENT), size[0], size[1], org[0], org[1], PRVM_G_FLOAT(OFS_PARM4), rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM6), flag); PRVM_G_FLOAT(OFS_RETURN) = 1; } /* @@ -3570,7 +3772,7 @@ void VM_drawsubpic(void) if(pos[2] || size[2]) Con_Printf("VM_drawsubpic: z value%s from %s discarded\n",(pos[2] && size[2]) ? "s" : " ",((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); - DrawQ_SuperPic(pos[0], pos[1], Draw_CachePic (picname), + DrawQ_SuperPic(pos[0], pos[1], Draw_CachePic_Flags (picname, CACHEPICFLAG_NOTPERSISTENT), size[0], size[1], srcPos[0], srcPos[1], rgb[0], rgb[1], rgb[2], alpha, srcPos[0] + srcSize[0], srcPos[1], rgb[0], rgb[1], rgb[2], alpha, @@ -3690,31 +3892,35 @@ void VM_keynumtostring (void) ========= VM_findkeysforcommand -string findkeysforcommand(string command) +string findkeysforcommand(string command, float bindmap) the returned string is an altstring ========= */ -#define NUMKEYS 5 // TODO: merge the constant in keys.c with this one somewhen - +#define FKFC_NUMKEYS 5 void M_FindKeysForCommand(const char *command, int *keys); void VM_findkeysforcommand(void) { const char *cmd; char ret[VM_STRINGTEMP_LENGTH]; - int keys[NUMKEYS]; + int keys[FKFC_NUMKEYS]; int i; + int bindmap; - VM_SAFEPARMCOUNT(1, VM_findkeysforcommand); + VM_SAFEPARMCOUNTRANGE(1, 2, VM_findkeysforcommand); cmd = PRVM_G_STRING(OFS_PARM0); + if(prog->argc == 2) + bindmap = bound(-1, PRVM_G_FLOAT(OFS_PARM1), MAX_BINDMAPS-1); + else + bindmap = 0; // consistent to "bind" VM_CheckEmptyString(cmd); - M_FindKeysForCommand(cmd, keys); + Key_FindKeysForCommand(cmd, keys, FKFC_NUMKEYS, bindmap); ret[0] = 0; - for(i = 0; i < NUMKEYS; i++) + for(i = 0; i < FKFC_NUMKEYS; i++) strlcat(ret, va(" \'%i\'", keys[i]), sizeof(ret)); PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(ret); @@ -3731,7 +3937,80 @@ void VM_stringtokeynum (void) { VM_SAFEPARMCOUNT( 1, VM_keynumtostring ); - PRVM_G_INT(OFS_RETURN) = Key_StringToKeynum(PRVM_G_STRING(OFS_PARM0)); + PRVM_G_FLOAT(OFS_RETURN) = Key_StringToKeynum(PRVM_G_STRING(OFS_PARM0)); +} + +/* +========= +VM_getkeybind + +string getkeybind(float key, float bindmap) +========= +*/ +void VM_getkeybind (void) +{ + int bindmap; + VM_SAFEPARMCOUNTRANGE(1, 2, VM_CL_getkeybind); + if(prog->argc == 2) + bindmap = bound(-1, PRVM_G_FLOAT(OFS_PARM1), MAX_BINDMAPS-1); + else + bindmap = 0; // consistent to "bind" + + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Key_GetBind((int)PRVM_G_FLOAT(OFS_PARM0), bindmap)); +} + +/* +========= +VM_setkeybind + +float setkeybind(float key, string cmd, float bindmap) +========= +*/ +void VM_setkeybind (void) +{ + int bindmap; + VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_setkeybind); + if(prog->argc == 3) + bindmap = bound(-1, PRVM_G_FLOAT(OFS_PARM2), MAX_BINDMAPS-1); + else + bindmap = 0; // consistent to "bind" + + PRVM_G_FLOAT(OFS_RETURN) = 0; + if(Key_SetBinding((int)PRVM_G_FLOAT(OFS_PARM0), bindmap, PRVM_G_STRING(OFS_PARM1))) + PRVM_G_FLOAT(OFS_RETURN) = 1; +} + +/* +========= +VM_getbindmap + +vector getbindmaps() +========= +*/ +void VM_getbindmaps (void) +{ + int fg, bg; + VM_SAFEPARMCOUNT(0, VM_CL_getbindmap); + Key_GetBindMap(&fg, &bg); + PRVM_G_VECTOR(OFS_RETURN)[0] = fg; + PRVM_G_VECTOR(OFS_RETURN)[1] = bg; + PRVM_G_VECTOR(OFS_RETURN)[2] = 0; +} + +/* +========= +VM_setbindmap + +float setbindmaps(vector bindmap) +========= +*/ +void VM_setbindmaps (void) +{ + VM_SAFEPARMCOUNT(1, VM_CL_setbindmap); + PRVM_G_FLOAT(OFS_RETURN) = 0; + if(PRVM_G_VECTOR(OFS_PARM0)[2] == 0) + if(Key_SetBindMap((int)PRVM_G_VECTOR(OFS_PARM0)[0], (int)PRVM_G_VECTOR(OFS_PARM0)[1])) + PRVM_G_FLOAT(OFS_RETURN) = 1; } // CL_Video interface functions @@ -3756,7 +4035,7 @@ void VM_cin_open( void ) VM_CheckEmptyString( file ); VM_CheckEmptyString( name ); - if( CL_OpenVideo( file, name, MENUOWNER ) ) + if( CL_OpenVideo( file, name, MENUOWNER, "" ) ) PRVM_G_FLOAT( OFS_RETURN ) = 1; else PRVM_G_FLOAT( OFS_RETURN ) = 0; @@ -4419,8 +4698,8 @@ static int BufStr_SortStringsUP (const void *in1, const void *in2) const char *a, *b; a = *((const char **) in1); b = *((const char **) in2); - if(!a[0]) return 1; - if(!b[0]) return -1; + if(!a || !a[0]) return 1; + if(!b || !b[0]) return -1; return strncmp(a, b, stringbuffers_sortlength); } @@ -4429,8 +4708,8 @@ static int BufStr_SortStringsDOWN (const void *in1, const void *in2) const char *a, *b; a = *((const char **) in1); b = *((const char **) in2); - if(!a[0]) return 1; - if(!b[0]) return -1; + if(!a || !a[0]) return 1; + if(!b || !b[0]) return -1; return strncmp(b, a, stringbuffers_sortlength); } @@ -4690,6 +4969,7 @@ void bufstr_set(float bufhandle, float string_index, string str) = #466; */ void VM_bufstr_set (void) { + size_t alloclen; int strindex; prvm_stringbuffer_t *stringbuffer; const char *news; @@ -4716,10 +4996,11 @@ void VM_bufstr_set (void) Mem_Free(stringbuffer->strings[strindex]); stringbuffer->strings[strindex] = NULL; - news = PRVM_G_STRING(OFS_PARM2); - if (news && news[0]) + if(PRVM_G_INT(OFS_PARM2)) { - size_t alloclen = strlen(news) + 1; + // not the NULL string! + news = PRVM_G_STRING(OFS_PARM2); + alloclen = strlen(news) + 1; stringbuffer->strings[strindex] = (char *)Mem_Alloc(prog->progs_mempool, alloclen); memcpy(stringbuffer->strings[strindex], news, alloclen); } @@ -4751,12 +5032,12 @@ void VM_bufstr_add (void) VM_Warning("VM_bufstr_add: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); return; } - string = PRVM_G_STRING(OFS_PARM1); - if(!string || !string[0]) + if(!PRVM_G_INT(OFS_PARM1)) // NULL string { VM_Warning("VM_bufstr_add: can not add an empty string to buffer %i in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); return; } + string = PRVM_G_STRING(OFS_PARM1); order = (int)PRVM_G_FLOAT(OFS_PARM2); if(order) strindex = stringbuffer->num_strings; @@ -5056,7 +5337,7 @@ void VM_strstrofs (void) if (!match) PRVM_G_FLOAT(OFS_RETURN) = -1; else - PRVM_G_FLOAT(OFS_RETURN) = match - instr; + PRVM_G_FLOAT(OFS_RETURN) = u8_strnlen(instr, match-instr); } //#222 string(string s, float index) str2chr (FTE_STRINGS) @@ -5439,7 +5720,7 @@ void VM_uri_escape (void) || (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || (*p == '-') || (*p == '_') || (*p == '.') - || (*p == '!') || (*p == '~') || (*p == '*') + || (*p == '!') || (*p == '~') || (*p == '\'') || (*p == '(') || (*p == ')')) *q++ = *p; else @@ -5573,7 +5854,7 @@ void VM_uri_get (void) handle->prognr = PRVM_GetProgNr(); handle->starttime = prog->starttime; handle->id = id; - ret = Curl_Begin_ToMemory(url, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle); + ret = Curl_Begin_ToMemory(url, 0, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle); if(ret) { PRVM_G_INT(OFS_RETURN) = 1; @@ -5636,6 +5917,26 @@ void VM_SV_getextresponse (void) } } +/* +========= +Common functions between menu.dat and clsprogs +========= +*/ + +//#349 float() isdemo +void VM_CL_isdemo (void) +{ + VM_SAFEPARMCOUNT(0, VM_CL_isdemo); + PRVM_G_FLOAT(OFS_RETURN) = cls.demoplayback; +} + +//#355 float() videoplaying +void VM_CL_videoplaying (void) +{ + VM_SAFEPARMCOUNT(0, VM_CL_videoplaying); + PRVM_G_FLOAT(OFS_RETURN) = cl_videoplaying; +} + /* ========= VM_M_callfunction @@ -5722,7 +6023,10 @@ void VM_sprintf(void) int width, precision, thisarg, flags; char formatbuf[16]; char *f; - qboolean isfloat; + int isfloat; + static int dummyivec[3] = {0, 0, 0}; + static float dummyvec[3] = {0, 0, 0}; + #define PRINTF_ALTERNATE 1 #define PRINTF_ZEROPAD 2 #define PRINTF_LEFT 4 @@ -5734,7 +6038,9 @@ void VM_sprintf(void) s = PRVM_G_STRING(OFS_PARM0); #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_STRING(a) (((a)>=1 && (a)argc) ? (PRVM_G_STRING(OFS_PARM0 + 3 * (a))) : "") for(;;) @@ -5757,6 +6063,7 @@ void VM_sprintf(void) precision = -1; thisarg = -1; flags = 0; + isfloat = -1; // is number following? if(*s >= '0' && *s <= '9') @@ -5879,14 +6186,13 @@ noflags: } } - isfloat = true; for(;;) { switch(*s) { - case 'h': isfloat = true; break; - case 'l': isfloat = false; break; - case 'L': isfloat = false; break; + case 'h': isfloat = 1; break; + case 'l': isfloat = 0; break; + case 'L': isfloat = 0; break; case 'j': break; case 'z': break; case 't': break; @@ -5897,6 +6203,15 @@ noflags: } nolength: + // now s points to the final directive char and is no longer changed + if(isfloat < 0) + { + if(*s == 'i') + isfloat = 0; + else + isfloat = 1; + } + if(thisarg < 0) thisarg = argpos++; @@ -5935,6 +6250,16 @@ nolength: precision = 6; o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (double) GETARG_FLOAT(thisarg) : (double) GETARG_INT(thisarg))); break; + case 'v': case 'V': + f[-2] += 'g' - 'v'; + if(precision < 0) // not set + precision = 6; + o += dpsnprintf(o, end - o, va("%s %s %s", /* NESTED SPRINTF IS NESTED */ formatbuf, formatbuf, formatbuf), + width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[0] : (double) GETARG_INTVECTOR(thisarg)[0]), + width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[1] : (double) GETARG_INTVECTOR(thisarg)[1]), + width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[2] : (double) GETARG_INTVECTOR(thisarg)[2]) + ); + break; case 'c': if(precision < 0) // not set precision = end - o - 1; @@ -6018,7 +6343,7 @@ void animatemodel(dp_model_t *model, prvm_edict_t *ed) skeleton_t *skeleton; int skeletonindex = -1; qboolean need = false; - if(!model->AnimateVertices) + if(!(model->surfmesh.isanimated && model->AnimateVertices)) { animatemodel_cache.data_vertex3f = model->surfmesh.data_vertex3f; animatemodel_cache.data_svector3f = model->surfmesh.data_svector3f; @@ -6031,13 +6356,13 @@ void animatemodel(dp_model_t *model, prvm_edict_t *ed) need |= (animatemodel_cache.model != model); VM_GenerateFrameGroupBlend(ed->priv.server->framegroupblend, ed); VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model); - need |= (memcmp(&animatemodel_cache.frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend))); + need |= (memcmp(&animatemodel_cache.frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend))) != 0; if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.skeletonindex))) skeletonindex = (int)val->_float - 1; if (!(skeletonindex >= 0 && skeletonindex < MAX_EDICTS && (skeleton = prog->skeletons[skeletonindex]) && skeleton->model->num_bones == ed->priv.server->skeleton.model->num_bones)) skeleton = NULL; need |= (animatemodel_cache.skeleton_p != skeleton); if(skeleton) - need |= (memcmp(&animatemodel_cache.skeleton, skeleton, sizeof(ed->priv.server->skeleton))); + need |= (memcmp(&animatemodel_cache.skeleton, skeleton, sizeof(ed->priv.server->skeleton))) != 0; if(!need) return; if(model->surfmesh.num_vertices > animatemodel_cache.max_vertices) @@ -6047,10 +6372,10 @@ void animatemodel(dp_model_t *model, prvm_edict_t *ed) if(animatemodel_cache.buf_svector3f) Mem_Free(animatemodel_cache.buf_svector3f); if(animatemodel_cache.buf_tvector3f) Mem_Free(animatemodel_cache.buf_tvector3f); if(animatemodel_cache.buf_normal3f) Mem_Free(animatemodel_cache.buf_normal3f); - animatemodel_cache.buf_vertex3f = Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices); - animatemodel_cache.buf_svector3f = Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices); - animatemodel_cache.buf_tvector3f = Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices); - animatemodel_cache.buf_normal3f = Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices); + animatemodel_cache.buf_vertex3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices); + animatemodel_cache.buf_svector3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices); + animatemodel_cache.buf_tvector3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices); + animatemodel_cache.buf_normal3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices); } animatemodel_cache.data_vertex3f = animatemodel_cache.buf_vertex3f; animatemodel_cache.data_svector3f = animatemodel_cache.buf_svector3f; @@ -6100,7 +6425,7 @@ static void applytransform_inverted(const vec3_t in, prvm_edict_t *ed, vec3_t ou { matrix4x4_t m, n; getmatrix(ed, &m); - Matrix4x4_Invert_Full(&m, &n); + Matrix4x4_Invert_Full(&n, &m); Matrix4x4_Transform3x3(&n, in, out); }