X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=prvm_cmds.c;h=81f62467cf03907f2bcbfd40ce139c5ee630d991;hp=ba832b81f63853aeba10e2a0952c3952fa261c74;hb=2075ae43356d724bae305ce8fd36ea570718b14a;hpb=704d101890948f0f496ce4fe73be523137c62117 diff --git a/prvm_cmds.c b/prvm_cmds.c index ba832b81..81f62467 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -99,7 +99,10 @@ void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroup memset(blend, 0, MAX_FRAMEBLENDS * sizeof(*blend)); - if (!model || !model->surfmesh.isanimated) + // rpolzer: Not testing isanimated here - a model might have + // "animations" that move no vertices (but only bones), thus rendering + // may assume it's not animated while processing can't. + if (!model) { blend[0].lerp = 1; return; @@ -2872,9 +2875,7 @@ VM_gettime float gettime(prvm_prog_t *prog) ========= */ -#ifdef CONFIG_CD float CDAudio_GetPosition(void); -#endif void VM_gettime(prvm_prog_t *prog) { int timer_index; @@ -2902,11 +2903,9 @@ void VM_gettime(prvm_prog_t *prog) case 3: // GETTIME_UPTIME PRVM_G_FLOAT(OFS_RETURN) = realtime; break; -#ifdef CONFIG_CD case 4: // GETTIME_CDTRACK PRVM_G_FLOAT(OFS_RETURN) = CDAudio_GetPosition(); break; -#endif default: VM_Warning(prog, "VM_gettime: %s: unsupported timer specified, returning realtime\n", prog->name); PRVM_G_FLOAT(OFS_RETURN) = realtime; @@ -3270,7 +3269,7 @@ string precache_pic(string pic) void VM_precache_pic(prvm_prog_t *prog) { const char *s; - int flags = 0; + int flags = CACHEPICFLAG_FAILONMISSING; VM_SAFEPARMCOUNTRANGE(1, 2, VM_precache_pic); @@ -3289,8 +3288,7 @@ void VM_precache_pic(prvm_prog_t *prog) flags |= CACHEPICFLAG_MIPMAP; } - // AK Draw_CachePic is supposed to always return a valid pointer - if( Draw_CachePic_Flags(s, flags)->tex == r_texture_notexture ) + if( !Draw_IsPicLoaded(Draw_CachePic_Flags(s, flags)) ) PRVM_G_INT(OFS_RETURN) = OFS_NULL; } @@ -3348,6 +3346,9 @@ void VM_drawcharacter(prvm_prog_t *prog) float sx, sy; VM_SAFEPARMCOUNT(6,VM_drawcharacter); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + character = (char) PRVM_G_FLOAT(OFS_PARM1); if(character == 0) { @@ -3398,6 +3399,9 @@ void VM_drawstring(prvm_prog_t *prog) float sx, sy; VM_SAFEPARMCOUNTRANGE(5,6,VM_drawstring); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + string = PRVM_G_STRING(OFS_PARM1); pos = PRVM_G_VECTOR(OFS_PARM0); scale = PRVM_G_VECTOR(OFS_PARM2); @@ -3447,6 +3451,9 @@ void VM_drawcolorcodedstring(prvm_prog_t *prog) VM_SAFEPARMCOUNTRANGE(5,6,VM_drawcolorcodedstring); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + if (prog->argc == 6) // full 6 parms, like normal drawstring { pos = PRVM_G_VECTOR(OFS_PARM0); @@ -3732,6 +3739,9 @@ void VM_drawpic(prvm_prog_t *prog) VM_SAFEPARMCOUNTRANGE(5,6,VM_drawpic); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + picname = PRVM_G_STRING(OFS_PARM1); VM_CheckEmptyString(prog, picname); @@ -3777,6 +3787,9 @@ void VM_drawrotpic(prvm_prog_t *prog) VM_SAFEPARMCOUNT(8,VM_drawrotpic); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + picname = PRVM_G_STRING(OFS_PARM1); VM_CheckEmptyString(prog, picname); @@ -3823,6 +3836,9 @@ void VM_drawsubpic(prvm_prog_t *prog) VM_SAFEPARMCOUNT(8,VM_drawsubpic); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + picname = PRVM_G_STRING(OFS_PARM2); VM_CheckEmptyString(prog, picname); @@ -3876,6 +3892,8 @@ void VM_drawfill(prvm_prog_t *prog) VM_SAFEPARMCOUNT(5,VM_drawfill); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; pos = PRVM_G_VECTOR(OFS_PARM0); size = PRVM_G_VECTOR(OFS_PARM1); @@ -3908,6 +3926,9 @@ void VM_drawsetcliparea(prvm_prog_t *prog) float x,y,w,h; VM_SAFEPARMCOUNT(4,VM_drawsetcliparea); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + x = bound(0, PRVM_G_FLOAT(OFS_PARM0), vid_conwidth.integer); y = bound(0, PRVM_G_FLOAT(OFS_PARM1), vid_conheight.integer); w = bound(0, PRVM_G_FLOAT(OFS_PARM2) + PRVM_G_FLOAT(OFS_PARM0) - x, (vid_conwidth.integer - x)); @@ -3927,6 +3948,9 @@ void VM_drawresetcliparea(prvm_prog_t *prog) { VM_SAFEPARMCOUNT(0,VM_drawresetcliparea); + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + DrawQ_ResetClipArea(); } @@ -3948,15 +3972,15 @@ void VM_getimagesize(prvm_prog_t *prog) VM_CheckEmptyString(prog, p); pic = Draw_CachePic_Flags (p, CACHEPICFLAG_NOTPERSISTENT); - if( pic->tex == r_texture_notexture ) + if (!Draw_IsPicLoaded(pic)) { 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)[0] = Draw_GetPicWidth(pic); + PRVM_G_VECTOR(OFS_RETURN)[1] = Draw_GetPicHeight(pic); } PRVM_G_VECTOR(OFS_RETURN)[2] = 0; } @@ -4356,6 +4380,10 @@ void VM_drawline (prvm_prog_t *prog) unsigned char flags; VM_SAFEPARMCOUNT(6, VM_drawline); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + width = PRVM_G_FLOAT(OFS_PARM0); c1 = PRVM_G_VECTOR(OFS_PARM1); c2 = PRVM_G_VECTOR(OFS_PARM2); @@ -4639,7 +4667,7 @@ static int BufStr_SortStringsDOWN (const void *in1, const void *in2) return strncmp(b, a, stringbuffers_sortlength); } -prvm_stringbuffer_t *BufStr_FindCreateReplace (prvm_prog_t *prog, int bufindex, int flags, char *format) +prvm_stringbuffer_t *BufStr_FindCreateReplace (prvm_prog_t *prog, int bufindex, int flags, const char *format) { prvm_stringbuffer_t *stringbuffer; int i; @@ -6036,11 +6064,14 @@ void VM_Cmd_Init(prvm_prog_t *prog) VM_Search_Init(prog); } +static void animatemodel_reset(prvm_prog_t *prog); + void VM_Cmd_Reset(prvm_prog_t *prog) { CL_PurgeOwner( MENUOWNER ); VM_Search_Reset(prog); VM_Files_CloseAll(prog); + animatemodel_reset(prog); } // #510 string(string input, ...) uri_escape (DP_QC_URI_ESCAPE) @@ -6833,9 +6864,8 @@ static dp_model_t *getmodel(prvm_prog_t *prog, prvm_edict_t *ed) return NULL; } -typedef struct +struct animatemodel_cache { - unsigned int progid; dp_model_t *model; frameblend_t frameblend[MAX_FRAMEBLENDS]; skeleton_t *skeleton_p; @@ -6849,61 +6879,74 @@ typedef struct float *buf_svector3f; float *buf_tvector3f; float *buf_normal3f; +}; + +static void animatemodel_reset(prvm_prog_t *prog) +{ + if (!prog->animatemodel_cache) + return; + if(prog->animatemodel_cache->buf_vertex3f) Mem_Free(prog->animatemodel_cache->buf_vertex3f); + if(prog->animatemodel_cache->buf_svector3f) Mem_Free(prog->animatemodel_cache->buf_svector3f); + if(prog->animatemodel_cache->buf_tvector3f) Mem_Free(prog->animatemodel_cache->buf_tvector3f); + if(prog->animatemodel_cache->buf_normal3f) Mem_Free(prog->animatemodel_cache->buf_normal3f); + Mem_Free(prog->animatemodel_cache); } -animatemodel_cache_t; -static animatemodel_cache_t animatemodel_cache; static void animatemodel(prvm_prog_t *prog, dp_model_t *model, prvm_edict_t *ed) { skeleton_t *skeleton; int skeletonindex = -1; qboolean need = false; + struct animatemodel_cache *animatemodel_cache; + if (!prog->animatemodel_cache) + { + prog->animatemodel_cache = (struct animatemodel_cache *)Mem_Alloc(prog->progs_mempool, sizeof(struct animatemodel_cache)); + memset(prog->animatemodel_cache, 0, sizeof(struct animatemodel_cache)); + } + animatemodel_cache = prog->animatemodel_cache; if(!(model->surfmesh.isanimated && model->AnimateVertices)) { - animatemodel_cache.data_vertex3f = model->surfmesh.data_vertex3f; - animatemodel_cache.data_svector3f = model->surfmesh.data_svector3f; - animatemodel_cache.data_tvector3f = model->surfmesh.data_tvector3f; - animatemodel_cache.data_normal3f = model->surfmesh.data_normal3f; + animatemodel_cache->data_vertex3f = model->surfmesh.data_vertex3f; + animatemodel_cache->data_svector3f = model->surfmesh.data_svector3f; + animatemodel_cache->data_tvector3f = model->surfmesh.data_tvector3f; + animatemodel_cache->data_normal3f = model->surfmesh.data_normal3f; return; } - if(animatemodel_cache.progid != prog->id) - memset(&animatemodel_cache, 0, sizeof(animatemodel_cache)); - need |= (animatemodel_cache.model != model); + need |= (animatemodel_cache->model != model); VM_GenerateFrameGroupBlend(prog, ed->priv.server->framegroupblend, ed); 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; + 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)) skeleton = NULL; - need |= (animatemodel_cache.skeleton_p != skeleton); + need |= (animatemodel_cache->skeleton_p != skeleton); if(skeleton) - need |= (memcmp(&animatemodel_cache.skeleton, skeleton, sizeof(ed->priv.server->skeleton))) != 0; + need |= (memcmp(&animatemodel_cache->skeleton, skeleton, sizeof(ed->priv.server->skeleton))) != 0; if(!need) return; - if(model->surfmesh.num_vertices > animatemodel_cache.max_vertices) - { - animatemodel_cache.max_vertices = model->surfmesh.num_vertices * 2; - if(animatemodel_cache.buf_vertex3f) Mem_Free(animatemodel_cache.buf_vertex3f); - 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 = (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; - animatemodel_cache.data_tvector3f = animatemodel_cache.buf_tvector3f; - animatemodel_cache.data_normal3f = animatemodel_cache.buf_normal3f; + if(model->surfmesh.num_vertices > animatemodel_cache->max_vertices) + { + animatemodel_cache->max_vertices = model->surfmesh.num_vertices * 2; + if(animatemodel_cache->buf_vertex3f) Mem_Free(animatemodel_cache->buf_vertex3f); + 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 = (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; + animatemodel_cache->data_tvector3f = animatemodel_cache->buf_tvector3f; + animatemodel_cache->data_normal3f = animatemodel_cache->buf_normal3f; VM_UpdateEdictSkeleton(prog, ed, model, ed->priv.server->frameblend); - model->AnimateVertices(model, ed->priv.server->frameblend, &ed->priv.server->skeleton, animatemodel_cache.data_vertex3f, animatemodel_cache.data_normal3f, animatemodel_cache.data_svector3f, animatemodel_cache.data_tvector3f); - animatemodel_cache.progid = prog->id; - animatemodel_cache.model = model; - memcpy(&animatemodel_cache.frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend)); - animatemodel_cache.skeleton_p = skeleton; + model->AnimateVertices(model, ed->priv.server->frameblend, &ed->priv.server->skeleton, animatemodel_cache->data_vertex3f, animatemodel_cache->data_normal3f, animatemodel_cache->data_svector3f, animatemodel_cache->data_tvector3f); + animatemodel_cache->model = model; + memcpy(&animatemodel_cache->frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend)); + animatemodel_cache->skeleton_p = skeleton; if(skeleton) - memcpy(&animatemodel_cache.skeleton, skeleton, sizeof(ed->priv.server->skeleton)); + memcpy(&animatemodel_cache->skeleton, skeleton, sizeof(ed->priv.server->skeleton)); } static void getmatrix(prvm_prog_t *prog, prvm_edict_t *ed, matrix4x4_t *out) @@ -6959,9 +7002,9 @@ static void clippointtosurface(prvm_prog_t *prog, prvm_edict_t *ed, dp_model_t * { // clip original point to each triangle of the surface and find the // triangle that is closest - v[0] = animatemodel_cache.data_vertex3f + e[0] * 3; - v[1] = animatemodel_cache.data_vertex3f + e[1] * 3; - v[2] = animatemodel_cache.data_vertex3f + e[2] * 3; + v[0] = prog->animatemodel_cache->data_vertex3f + e[0] * 3; + v[1] = prog->animatemodel_cache->data_vertex3f + e[1] * 3; + v[2] = prog->animatemodel_cache->data_vertex3f + e[2] * 3; TriangleNormal(v[0], v[1], v[2], facenormal); VectorNormalize(facenormal); offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal); @@ -7026,7 +7069,7 @@ 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, result); + applytransform_forward(prog, &(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; @@ -7061,22 +7104,22 @@ 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, result); + applytransform_forward(prog, &(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, result); + applytransform_forward_direction(prog, &(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, result); + applytransform_forward_direction(prog, &(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, result); + applytransform_forward_direction(prog, &(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; @@ -7121,7 +7164,7 @@ void VM_getsurfacenormal(prvm_prog_t *prog) // note: this only returns the first triangle, so it doesn't work very // 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); + TriangleNormal((prog->animatemodel_cache->data_vertex3f + 3 * surface->num_firstvertex), (prog->animatemodel_cache->data_vertex3f + 3 * surface->num_firstvertex) + 3, (prog->animatemodel_cache->data_vertex3f + 3 * surface->num_firstvertex) + 6, normal); applytransform_forward_normal(prog, normal, PRVM_G_EDICT(OFS_PARM0), result); VectorNormalize(result); VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN));