X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=prvm_cmds.c;h=a1aef535a0842a3de2137488d4feef0d744b7ce3;hb=cbbf18e419ad4d6b1848192cf86aba37b9fb6df4;hp=3976608f3e2af8020b6b398915a688f7968424f5;hpb=9e2930c2fa043bbc2fe78735984fe6cc4d174534;p=xonotic%2Fdarkplaces.git diff --git a/prvm_cmds.c b/prvm_cmds.c index 3976608f..a1aef535 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++) @@ -3234,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; } @@ -3689,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; } /* @@ -3734,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; } /* @@ -3782,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, @@ -3902,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); @@ -3943,21 +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) +string getkeybind(float key, float bindmap) ========= */ -const char *Key_GetBind (int key); void VM_getkeybind (void) { - VM_SAFEPARMCOUNT(1, VM_CL_getkeybind); - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Key_GetBind((int)PRVM_G_FLOAT(OFS_PARM0))); + 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 @@ -5748,6 +5801,10 @@ typedef struct double starttime; float id; char buffer[MAX_INPUTLINE]; + unsigned char *postdata; // free when uri_to_prog_t is freed + size_t postlen; + char *sigdata; // free when uri_to_prog_t is freed + size_t siglen; } uri_to_prog_t; @@ -5758,6 +5815,10 @@ static void uri_to_string_callback(int status, size_t length_received, unsigned if(!PRVM_ProgLoaded(handle->prognr)) { // curl reply came too late... so just drop it + if(handle->postdata) + Z_Free(handle->postdata); + if(handle->sigdata) + Z_Free(handle->sigdata); Z_Free(handle); return; } @@ -5777,6 +5838,10 @@ static void uri_to_string_callback(int status, size_t length_received, unsigned } PRVM_End; + if(handle->postdata) + Z_Free(handle->postdata); + if(handle->sigdata) + Z_Free(handle->sigdata); Z_Free(handle); } @@ -5788,26 +5853,157 @@ void VM_uri_get (void) float id; qboolean ret; uri_to_prog_t *handle; + const char *posttype = NULL; + const char *postseparator = NULL; + int poststringbuffer = -1; + int postkeyid = -1; + const char *query_string = NULL; + size_t lq; if(!prog->funcoffsets.URI_Get_Callback) PRVM_ERROR("uri_get called by %s without URI_Get_Callback defined", PRVM_NAME); - VM_SAFEPARMCOUNT(2, VM_uri_get); + VM_SAFEPARMCOUNTRANGE(2, 6, VM_uri_get); url = PRVM_G_STRING(OFS_PARM0); id = PRVM_G_FLOAT(OFS_PARM1); + if(prog->argc >= 3) + posttype = PRVM_G_STRING(OFS_PARM2); + if(prog->argc >= 4) + postseparator = PRVM_G_STRING(OFS_PARM3); + if(prog->argc >= 5) + poststringbuffer = PRVM_G_FLOAT(OFS_PARM4); + if(prog->argc >= 6) + postkeyid = PRVM_G_FLOAT(OFS_PARM5); handle = (uri_to_prog_t *) Z_Malloc(sizeof(*handle)); // this can't be the prog's mem pool, as curl may call the callback later! + query_string = strchr(url, '?'); + if(query_string) + ++query_string; + lq = query_string ? strlen(query_string) : 0; + handle->prognr = PRVM_GetProgNr(); handle->starttime = prog->starttime; handle->id = id; - ret = Curl_Begin_ToMemory(url, 0, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle); + if(postseparator) + { + size_t l = strlen(postseparator); + if(poststringbuffer >= 0) + { + size_t ltotal; + int i; + // "implode" + prvm_stringbuffer_t *stringbuffer; + stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, poststringbuffer); + if(!stringbuffer) + { + VM_Warning("uri_get: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME); + return; + } + ltotal = 0; + for(i = 0;i < stringbuffer->num_strings;i++) + { + if(i > 0) + ltotal += l; + if(stringbuffer->strings[i]) + ltotal += strlen(stringbuffer->strings[i]); + } + handle->postdata = (unsigned char *)Z_Malloc(ltotal + 1 + lq); + handle->postlen = ltotal; + ltotal = 0; + for(i = 0;i < stringbuffer->num_strings;i++) + { + if(i > 0) + { + memcpy(handle->postdata + ltotal, postseparator, l); + ltotal += l; + } + if(stringbuffer->strings[i]) + { + memcpy(handle->postdata + ltotal, stringbuffer->strings[i], strlen(stringbuffer->strings[i])); + ltotal += strlen(stringbuffer->strings[i]); + } + } + if(ltotal != handle->postlen) + PRVM_ERROR ("%s: string buffer content size mismatch, possible overrun", PRVM_NAME); + } + else + { + handle->postdata = (unsigned char *)Z_Malloc(l + 1 + lq); + handle->postlen = l; + memcpy(handle->postdata, postseparator, l); + } + handle->postdata[handle->postlen] = 0; + if(query_string) + memcpy(handle->postdata + handle->postlen + 1, query_string, lq); + if(postkeyid >= 0) + { + // POST: we sign postdata \0 query string + size_t ll; + handle->sigdata = (char *)Z_Malloc(8192); + strlcpy(handle->sigdata, "X-D0-Blind-ID-Detached-Signature: ", 8192); + l = strlen(handle->sigdata); + handle->siglen = Crypto_SignDataDetached(handle->postdata, handle->postlen + 1 + lq, postkeyid, handle->sigdata + l, 8192 - l); + if(!handle->siglen) + { + Z_Free(handle->sigdata); + handle->sigdata = NULL; + goto out1; + } + ll = base64_encode((unsigned char *) (handle->sigdata + l), handle->siglen, 8192 - l - 1); + if(!ll) + { + Z_Free(handle->sigdata); + handle->sigdata = NULL; + goto out1; + } + handle->siglen = l + ll; + handle->sigdata[handle->siglen] = 0; + } +out1: + ret = Curl_Begin_ToMemory_POST(url, handle->sigdata, 0, posttype, handle->postdata, handle->postlen, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle); + } + else + { + if(postkeyid >= 0 && query_string) + { + // GET: we sign JUST the query string + size_t l, ll; + handle->sigdata = (char *)Z_Malloc(8192); + strlcpy(handle->sigdata, "X-D0-Blind-ID-Detached-Signature: ", 8192); + l = strlen(handle->sigdata); + handle->siglen = Crypto_SignDataDetached(query_string, lq, postkeyid, handle->sigdata + l, 8192 - l); + if(!handle->siglen) + { + Z_Free(handle->sigdata); + handle->sigdata = NULL; + goto out2; + } + ll = base64_encode((unsigned char *) (handle->sigdata + l), handle->siglen, 8192 - l - 1); + if(!ll) + { + Z_Free(handle->sigdata); + handle->sigdata = NULL; + goto out2; + } + handle->siglen = l + ll; + handle->sigdata[handle->siglen] = 0; + } +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); + } if(ret) { PRVM_G_INT(OFS_RETURN) = 1; } else { + if(handle->postdata) + Z_Free(handle->postdata); + if(handle->sigdata) + Z_Free(handle->sigdata); Z_Free(handle); PRVM_G_INT(OFS_RETURN) = 0; } @@ -6290,7 +6486,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; @@ -6303,13 +6499,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) @@ -6319,10 +6515,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;