X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=prvm_cmds.c;h=887192dda0456c79ae645688cebc4a9ec1a70561;hp=47e94fe61299bf63ad19ee596590c01606c71dd5;hb=16742571f9a7d696a654668febdc10b4f4affd57;hpb=ded16fd66f1a999d35ee57f989f881f205a428c7 diff --git a/prvm_cmds.c b/prvm_cmds.c index 47e94fe6..887192dd 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -206,6 +206,8 @@ void VM_sprint (void) int clientnum; char string[VM_STRINGTEMP_LENGTH]; + VM_SAFEPARMCOUNTRANGE(1, 8, VM_sprint); + //find client for this entity clientnum = (int)PRVM_G_FLOAT(OFS_PARM0); if (!sv.active || clientnum < 0 || clientnum >= svs.maxclients || !svs.clients[clientnum].active) @@ -229,13 +231,14 @@ VM_centerprint single print to the screen -centerprint(clientent, value) +centerprint(value) ================= */ void VM_centerprint (void) { char string[VM_STRINGTEMP_LENGTH]; + VM_SAFEPARMCOUNTRANGE(1, 8, VM_centerprint); VM_VarString(0, string, sizeof(string)); SCR_CenterPrint(string); } @@ -377,49 +380,6 @@ void VM_random (void) PRVM_G_FLOAT(OFS_RETURN) = lhrandom(0, 1); } -/* -================= -PF_sound - -Each entity can have eight independant sound sources, like voice, -weapon, feet, etc. - -Channel 0 is an auto-allocate channel, the others override anything -already running on that entity/channel pair. - -An attenuation of 0 will play full volume everywhere in the level. -Larger attenuations will drop off. - -================= -*/ -/* -void PF_sound (void) -{ - char *sample; - int channel; - prvm_edict_t *entity; - int volume; - float attenuation; - - entity = PRVM_G_EDICT(OFS_PARM0); - channel = PRVM_G_FLOAT(OFS_PARM1); - sample = PRVM_G_STRING(OFS_PARM2); - volume = PRVM_G_FLOAT(OFS_PARM3) * 255; - attenuation = PRVM_G_FLOAT(OFS_PARM4); - - if (volume < 0 || volume > 255) - Host_Error ("SV_StartSound: volume = %i", volume); - - if (attenuation < 0 || attenuation > 4) - Host_Error ("SV_StartSound: attenuation = %f", attenuation); - - if (channel < 0 || channel > 7) - Host_Error ("SV_StartSound: channel = %i", channel); - - SV_StartSound (entity, channel, sample, volume, attenuation); -} -*/ - /* ========= VM_localsound @@ -472,6 +432,7 @@ cmd (string, ...) void VM_localcmd (void) { char string[VM_STRINGTEMP_LENGTH]; + VM_SAFEPARMCOUNTRANGE(1, 8, VM_localcmd); VM_VarString(0, string, sizeof(string)); Cbuf_AddText(string); } @@ -552,6 +513,7 @@ dprint(...[string]) void VM_dprint (void) { char string[VM_STRINGTEMP_LENGTH]; + VM_SAFEPARMCOUNTRANGE(1, 8, VM_dprint); if (developer.integer) { VM_VarString(0, string, sizeof(string)); @@ -651,6 +613,7 @@ float stof(...[string]) void VM_stof(void) { char string[VM_STRINGTEMP_LENGTH]; + VM_SAFEPARMCOUNTRANGE(1, 8, VM_stof); VM_VarString(0, string, sizeof(string)); PRVM_G_FLOAT(OFS_RETURN) = atof(string); } @@ -700,7 +663,8 @@ void VM_strftime(void) struct tm *tm; char fmt[VM_STRINGTEMP_LENGTH]; char result[VM_STRINGTEMP_LENGTH]; - VM_VarString(0, fmt, sizeof(fmt)); + VM_SAFEPARMCOUNTRANGE(2, 8, VM_strftime); + VM_VarString(1, fmt, sizeof(fmt)); t = time(NULL); if (PRVM_G_FLOAT(OFS_PARM0)) tm = localtime(&t); @@ -726,6 +690,7 @@ entity spawn() void VM_spawn (void) { prvm_edict_t *ed; + VM_SAFEPARMCOUNT(0, VM_spawn); prog->xfunction->builtinsprofile += 20; ed = PRVM_ED_Alloc(); VM_RETURN_EDICT(ed); @@ -1022,6 +987,46 @@ void VM_findchainflags (void) VM_RETURN_EDICT(chain); } +/* +========= +VM_precache_sound + +string precache_sound (string sample) +========= +*/ +void VM_precache_sound (void) +{ + const char *s; + + VM_SAFEPARMCOUNT(1, VM_precache_sound); + + s = PRVM_G_STRING(OFS_PARM0); + PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0); + VM_CheckEmptyString(s); + + if(snd_initialized.integer && !S_PrecacheSound(s, true, false)) + { + VM_Warning("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME); + return; + } +} + +/* +================= +VM_precache_file + +returns the same string as output + +does nothing, only used by qcc to build .pak archives +================= +*/ +void VM_precache_file (void) +{ + VM_SAFEPARMCOUNT(1,VM_precache_file); + // precache_file is only used to copy files with qcc, it does nothing + PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0); +} + /* ========= VM_coredump @@ -1170,6 +1175,8 @@ void VM_nextent (void) int i; prvm_edict_t *ent; + VM_SAFEPARMCOUNT(1, VM_nextent); + i = PRVM_G_EDICTNUM(OFS_PARM0); while (1) { @@ -1358,7 +1365,7 @@ void VM_randomvec (void) ========= VM_registercvar -float registercvar (string name, string value, float flags) +float registercvar (string name, string value[, float flags]) ========= */ void VM_registercvar (void) @@ -1366,11 +1373,11 @@ void VM_registercvar (void) const char *name, *value; int flags; - VM_SAFEPARMCOUNT(3,VM_registercvar); + VM_SAFEPARMCOUNTRANGE(2, 3, VM_registercvar); name = PRVM_G_STRING(OFS_PARM0); value = PRVM_G_STRING(OFS_PARM1); - flags = (int)PRVM_G_FLOAT(OFS_PARM2); + flags = prog->argc >= 3 ? (int)PRVM_G_FLOAT(OFS_PARM2) : 0; PRVM_G_FLOAT(OFS_RETURN) = 0; if(flags > CVAR_MAXFLAGSVAL) @@ -1392,6 +1399,7 @@ void VM_registercvar (void) PRVM_G_FLOAT(OFS_RETURN) = 1; // success } + /* ================= VM_min @@ -1403,20 +1411,19 @@ float min(float a, float b, ...[float]) */ void VM_min (void) { + VM_SAFEPARMCOUNTRANGE(2, 8, VM_min); // LordHavoc: 3+ argument enhancement suggested by FrikaC - if (prog->argc == 2) - PRVM_G_FLOAT(OFS_RETURN) = min(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)); - else if (prog->argc >= 3) + if (prog->argc >= 3) { int i; float f = PRVM_G_FLOAT(OFS_PARM0); for (i = 1;i < prog->argc;i++) - if (PRVM_G_FLOAT((OFS_PARM0+i*3)) < f) + if (f > PRVM_G_FLOAT((OFS_PARM0+i*3))) f = PRVM_G_FLOAT((OFS_PARM0+i*3)); PRVM_G_FLOAT(OFS_RETURN) = f; } else - PRVM_ERROR("VM_min: %s must supply at least 2 floats", PRVM_NAME); + PRVM_G_FLOAT(OFS_RETURN) = min(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)); } /* @@ -1430,20 +1437,19 @@ float max(float a, float b, ...[float]) */ void VM_max (void) { + VM_SAFEPARMCOUNTRANGE(2, 8, VM_max); // LordHavoc: 3+ argument enhancement suggested by FrikaC - if (prog->argc == 2) - PRVM_G_FLOAT(OFS_RETURN) = max(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)); - else if (prog->argc >= 3) + if (prog->argc >= 3) { int i; float f = PRVM_G_FLOAT(OFS_PARM0); for (i = 1;i < prog->argc;i++) - if (PRVM_G_FLOAT((OFS_PARM0+i*3)) > f) + if (f < PRVM_G_FLOAT((OFS_PARM0+i*3))) f = PRVM_G_FLOAT((OFS_PARM0+i*3)); PRVM_G_FLOAT(OFS_RETURN) = f; } else - PRVM_ERROR("VM_max: %s must supply at least 2 floats", PRVM_NAME); + PRVM_G_FLOAT(OFS_RETURN) = max(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)); } /* @@ -1476,24 +1482,6 @@ void VM_pow (void) PRVM_G_FLOAT(OFS_RETURN) = pow(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)); } -/* -================= -VM_copyentity - -copies data from one entity to another - -copyentity(entity src, entity dst) -================= -*/ -void VM_copyentity (void) -{ - prvm_edict_t *in, *out; - VM_SAFEPARMCOUNT(2,VM_copyentity); - in = PRVM_G_EDICT(OFS_PARM0); - out = PRVM_G_EDICT(OFS_PARM1); - memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4); -} - void VM_Files_Init(void) { int i; @@ -1512,7 +1500,7 @@ void VM_Files_CloseAll(void) } } -qfile_t *VM_GetFileHandle( int index ) +static qfile_t *VM_GetFileHandle( int index ) { if (index < 0 || index >= PRVM_MAX_OPENFILES) { @@ -1707,6 +1695,37 @@ void VM_fputs(void) Con_Printf("fputs: %s: %s\n", PRVM_NAME, string); } +/* +========= +VM_writetofile + + writetofile(float fhandle, entity ent) +========= +*/ +void VM_writetofile(void) +{ + prvm_edict_t * ent; + qfile_t *file; + + VM_SAFEPARMCOUNT(2, VM_writetofile); + + file = VM_GetFileHandle( (int)PRVM_G_FLOAT(OFS_PARM0) ); + if( !file ) + { + VM_Warning("VM_writetofile: invalid or closed file handle\n"); + return; + } + + ent = PRVM_G_EDICT(OFS_PARM1); + if(ent->priv.required->free) + { + VM_Warning("VM_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent)); + return; + } + + PRVM_ED_Write (file, ent); +} + /* ========= VM_strlen @@ -1862,9 +1881,7 @@ string strcat(string,string,...[string]) void VM_strcat(void) { char s[VM_STRINGTEMP_LENGTH]; - - if(prog->argc < 1) - PRVM_ERROR("VM_strcat wrong parameter count (min. 1 expected ) !"); + VM_SAFEPARMCOUNTRANGE(1, 8, VM_strcat); VM_VarString(0, s, sizeof(s)); PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(s); @@ -2053,7 +2070,7 @@ void VM_isserver(void) { VM_SAFEPARMCOUNT(0,VM_serverstate); - PRVM_G_FLOAT(OFS_RETURN) = sv.active; + PRVM_G_FLOAT(OFS_RETURN) = sv.active && (svs.maxclients > 1 || cls.state == ca_dedicated); } /* @@ -2831,18 +2848,51 @@ void VM_cin_restart( void ) CL_RestartVideo( video ); } +/* +============== +VM_makevectors + +Writes new values for v_forward, v_up, and v_right based on angles +void makevectors(vector angle) +============== +*/ +void VM_makevectors (void) +{ + prvm_eval_t *valforward, *valright, *valup; + valforward = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_forward); + valright = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_right); + valup = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_up); + if (!valforward || !valright || !valup) + { + VM_Warning("makevectors: could not find v_forward, v_right, or v_up global variables\n"); + return; + } + VM_SAFEPARMCOUNT(1, VM_makevectors); + AngleVectors (PRVM_G_VECTOR(OFS_PARM0), valforward->vector, valright->vector, valup->vector); +} + /* ============== VM_vectorvectors Writes new values for v_forward, v_up, and v_right based on the given forward vector -vectorvectors(vector, vector) +vectorvectors(vector) ============== */ void VM_vectorvectors (void) { - VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward); - VectorVectors(prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up); + prvm_eval_t *valforward, *valright, *valup; + valforward = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_forward); + valright = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_right); + valup = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_up); + if (!valforward || !valright || !valup) + { + VM_Warning("vectorvectors: could not find v_forward, v_right, or v_up global variables\n"); + return; + } + VM_SAFEPARMCOUNT(1, VM_vectorvectors); + VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), valforward->vector); + VectorVectors(valforward->vector, valright->vector, valup->vector); } /* @@ -2868,364 +2918,6 @@ void VM_drawline (void) DrawQ_Line(width, c1[0], c1[1], c2[0], c2[1], rgb[0], rgb[1], rgb[2], alpha, flags); } -//==================== -//QC POLYGON functions -//==================== - -typedef struct -{ - rtexture_t *tex; - float data[36]; //[515]: enough for polygons - unsigned char flags; //[515]: + VM_POLYGON_2D and VM_POLYGON_FL4V flags -}vm_polygon_t; - -//static float vm_polygon_linewidth = 1; -static mempool_t *vm_polygons_pool = NULL; -static unsigned char vm_current_vertices = 0; -static qboolean vm_polygons_initialized = false; -static vm_polygon_t *vm_polygons = NULL; -static unsigned long vm_polygons_num = 0, vm_drawpolygons_num = 0; //[515]: ok long on 64bit ? -static qboolean vm_polygonbegin = false; //[515]: for "no-crap-on-the-screen" check -#define VM_DEFPOLYNUM 64 //[515]: enough for default ? - -#define VM_POLYGON_FL3V 16 //more than 2 vertices (used only for lines) -#define VM_POLYGON_FLLINES 32 -#define VM_POLYGON_FL2D 64 -#define VM_POLYGON_FL4V 128 //4 vertices - -void VM_InitPolygons (void) -{ - vm_polygons_pool = Mem_AllocPool("VMPOLY", 0, NULL); - vm_polygons = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, VM_DEFPOLYNUM*sizeof(vm_polygon_t)); - memset(vm_polygons, 0, VM_DEFPOLYNUM*sizeof(vm_polygon_t)); - vm_polygons_num = VM_DEFPOLYNUM; - vm_drawpolygons_num = 0; - vm_polygonbegin = false; - vm_polygons_initialized = true; -} - -void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) -{ - int surfacelistindex; - // LordHavoc: FIXME: this is stupid code - for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) - { - const vm_polygon_t *p = &vm_polygons[surfacelist[surfacelistindex]]; - int flags = p->flags & 0x0f; - - if(flags == DRAWFLAG_ADDITIVE) - GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); - else if(flags == DRAWFLAG_MODULATE) - GL_BlendFunc(GL_DST_COLOR, GL_ZERO); - else if(flags == DRAWFLAG_2XMODULATE) - GL_BlendFunc(GL_DST_COLOR,GL_SRC_COLOR); - else - GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - R_Mesh_TexBind(0, R_GetTexture(p->tex)); - - CHECKGLERROR - //[515]: is speed is max ? - if(p->flags & VM_POLYGON_FLLINES) //[515]: lines - { - qglLineWidth(p->data[13]);CHECKGLERROR - qglBegin(GL_LINE_LOOP); - qglTexCoord1f (p->data[12]); - qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]); - qglVertex3f (p->data[0] , p->data[1], p->data[2]); - - qglTexCoord1f (p->data[14]); - qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]); - qglVertex3f (p->data[3] , p->data[4], p->data[5]); - - if(p->flags & VM_POLYGON_FL3V) - { - qglTexCoord1f (p->data[16]); - qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]); - qglVertex3f (p->data[6] , p->data[7], p->data[8]); - - if(p->flags & VM_POLYGON_FL4V) - { - qglTexCoord1f (p->data[18]); - qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]); - qglVertex3f (p->data[9] , p->data[10], p->data[11]); - } - } - qglEnd(); - CHECKGLERROR - } - else - { - qglBegin(GL_POLYGON); - qglTexCoord2f (p->data[12], p->data[13]); - qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]); - qglVertex3f (p->data[0] , p->data[1], p->data[2]); - - qglTexCoord2f (p->data[14], p->data[15]); - qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]); - qglVertex3f (p->data[3] , p->data[4], p->data[5]); - - qglTexCoord2f (p->data[16], p->data[17]); - qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]); - qglVertex3f (p->data[6] , p->data[7], p->data[8]); - - if(p->flags & VM_POLYGON_FL4V) - { - qglTexCoord2f (p->data[18], p->data[19]); - qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]); - qglVertex3f (p->data[9] , p->data[10], p->data[11]); - } - qglEnd(); - CHECKGLERROR - } - } -} - -void VM_AddPolygonTo2DScene (vm_polygon_t *p) -{ - drawqueuemesh_t mesh; - static int picelements[6] = {0, 1, 2, 0, 2, 3}; - - mesh.texture = p->tex; - mesh.data_element3i = picelements; - mesh.data_vertex3f = p->data; - mesh.data_texcoord2f = p->data + 12; - mesh.data_color4f = p->data + 20; - if(p->flags & VM_POLYGON_FL4V) - { - mesh.num_vertices = 4; - mesh.num_triangles = 2; - } - else - { - mesh.num_vertices = 3; - mesh.num_triangles = 1; - } - if(p->flags & VM_POLYGON_FLLINES) //[515]: lines - DrawQ_LineLoop (&mesh, (p->flags&0x0f)); - else - DrawQ_Mesh (&mesh, (p->flags&0x0f)); -} - -//void(string texturename, float flag, float 2d, float lines) R_BeginPolygon -void VM_R_PolygonBegin (void) -{ - vm_polygon_t *p; - const char *picname; - if(prog->argc < 2) - VM_SAFEPARMCOUNT(2, VM_R_PolygonBegin); - - if(!vm_polygons_initialized) - VM_InitPolygons(); - if(vm_polygonbegin) - { - VM_Warning("VM_R_PolygonBegin: called twice without VM_R_PolygonEnd after first\n"); - return; - } - if(vm_drawpolygons_num >= vm_polygons_num) - { - p = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, 2 * vm_polygons_num * sizeof(vm_polygon_t)); - memset(p, 0, 2 * vm_polygons_num * sizeof(vm_polygon_t)); - memcpy(p, vm_polygons, vm_polygons_num * sizeof(vm_polygon_t)); - Mem_Free(vm_polygons); - vm_polygons = p; - vm_polygons_num *= 2; - } - p = &vm_polygons[vm_drawpolygons_num]; - picname = PRVM_G_STRING(OFS_PARM0); - if(picname[0]) - p->tex = Draw_CachePic(picname, true)->tex; - else - p->tex = r_texture_white; - p->flags = (unsigned char)PRVM_G_FLOAT(OFS_PARM1); - vm_current_vertices = 0; - vm_polygonbegin = true; - if(prog->argc >= 3) - { - if(PRVM_G_FLOAT(OFS_PARM2)) - p->flags |= VM_POLYGON_FL2D; - if(prog->argc >= 4 && PRVM_G_FLOAT(OFS_PARM3)) - { - p->data[13] = PRVM_G_FLOAT(OFS_PARM3); //[515]: linewidth - p->flags |= VM_POLYGON_FLLINES; - } - } -} - -//void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex -void VM_R_PolygonVertex (void) -{ - float *coords, *tx, *rgb, alpha; - vm_polygon_t *p; - VM_SAFEPARMCOUNT(4, VM_R_PolygonVertex); - - if(!vm_polygonbegin) - { - VM_Warning("VM_R_PolygonVertex: VM_R_PolygonBegin wasn't called\n"); - return; - } - coords = PRVM_G_VECTOR(OFS_PARM0); - tx = PRVM_G_VECTOR(OFS_PARM1); - rgb = PRVM_G_VECTOR(OFS_PARM2); - alpha = PRVM_G_FLOAT(OFS_PARM3); - - p = &vm_polygons[vm_drawpolygons_num]; - if(vm_current_vertices > 4) - { - VM_Warning("VM_R_PolygonVertex: may have 4 vertices max\n"); - return; - } - - p->data[vm_current_vertices*3] = coords[0]; - p->data[1+vm_current_vertices*3] = coords[1]; - p->data[2+vm_current_vertices*3] = coords[2]; - - p->data[12+vm_current_vertices*2] = tx[0]; - if(!(p->flags & VM_POLYGON_FLLINES)) - p->data[13+vm_current_vertices*2] = tx[1]; - - p->data[20+vm_current_vertices*4] = rgb[0]; - p->data[21+vm_current_vertices*4] = rgb[1]; - p->data[22+vm_current_vertices*4] = rgb[2]; - p->data[23+vm_current_vertices*4] = alpha; - - vm_current_vertices++; - if(vm_current_vertices == 4) - p->flags |= VM_POLYGON_FL4V; - else - if(vm_current_vertices == 3) - p->flags |= VM_POLYGON_FL3V; -} - -//void() R_EndPolygon -void VM_R_PolygonEnd (void) -{ - if(!vm_polygonbegin) - { - VM_Warning("VM_R_PolygonEnd: VM_R_PolygonBegin wasn't called\n"); - return; - } - vm_polygonbegin = false; - if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES)) - { - if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D - VM_AddPolygonTo2DScene(&vm_polygons[vm_drawpolygons_num]); - else - vm_drawpolygons_num++; - } - else - VM_Warning("VM_R_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices); -} - -void VM_AddPolygonsToMeshQueue (void) -{ - int i; - if(!vm_drawpolygons_num) - return; - R_Mesh_Matrix(&identitymatrix); - GL_CullFace(GL_NONE); - for(i = 0;i < (int)vm_drawpolygons_num;i++) - VM_DrawPolygonCallback(NULL, NULL, 1, &i); - vm_drawpolygons_num = 0; -} - -void Debug_PolygonBegin(const char *picname, int flags, qboolean draw2d, float linewidth) -{ - vm_polygon_t *p; - - if(!vm_polygons_initialized) - VM_InitPolygons(); - if(vm_polygonbegin) - { - Con_Printf("Debug_PolygonBegin: called twice without Debug_PolygonEnd after first\n"); - return; - } - // limit polygons to a vaguely sane amount, beyond this each one just - // replaces the last one - vm_drawpolygons_num = min(vm_drawpolygons_num, (1<<20)-1); - if(vm_drawpolygons_num >= vm_polygons_num) - { - p = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, 2 * vm_polygons_num * sizeof(vm_polygon_t)); - memset(p, 0, 2 * vm_polygons_num * sizeof(vm_polygon_t)); - memcpy(p, vm_polygons, vm_polygons_num * sizeof(vm_polygon_t)); - Mem_Free(vm_polygons); - vm_polygons = p; - vm_polygons_num *= 2; - } - p = &vm_polygons[vm_drawpolygons_num]; - if(picname && picname[0]) - p->tex = Draw_CachePic(picname, true)->tex; - else - p->tex = r_texture_white; - p->flags = flags; - vm_current_vertices = 0; - vm_polygonbegin = true; - if(draw2d) - p->flags |= VM_POLYGON_FL2D; - if(linewidth) - { - p->data[13] = linewidth; //[515]: linewidth - p->flags |= VM_POLYGON_FLLINES; - } -} - -void Debug_PolygonVertex(float x, float y, float z, float s, float t, float r, float g, float b, float a) -{ - vm_polygon_t *p; - - if(!vm_polygonbegin) - { - Con_Printf("Debug_PolygonVertex: Debug_PolygonBegin wasn't called\n"); - return; - } - - p = &vm_polygons[vm_drawpolygons_num]; - if(vm_current_vertices > 4) - { - Con_Printf("Debug_PolygonVertex: may have 4 vertices max\n"); - return; - } - - p->data[vm_current_vertices*3] = x; - p->data[1+vm_current_vertices*3] = y; - p->data[2+vm_current_vertices*3] = z; - - p->data[12+vm_current_vertices*2] = s; - if(!(p->flags & VM_POLYGON_FLLINES)) - p->data[13+vm_current_vertices*2] = t; - - p->data[20+vm_current_vertices*4] = r; - p->data[21+vm_current_vertices*4] = g; - p->data[22+vm_current_vertices*4] = b; - p->data[23+vm_current_vertices*4] = a; - - vm_current_vertices++; - if(vm_current_vertices == 4) - p->flags |= VM_POLYGON_FL4V; - else - if(vm_current_vertices == 3) - p->flags |= VM_POLYGON_FL3V; -} - -void Debug_PolygonEnd(void) -{ - if(!vm_polygonbegin) - { - Con_Printf("Debug_PolygonEnd: Debug_PolygonBegin wasn't called\n"); - return; - } - vm_polygonbegin = false; - if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES)) - { - if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D - VM_AddPolygonTo2DScene(&vm_polygons[vm_drawpolygons_num]); - else - vm_drawpolygons_num++; - } - else - Con_Printf("Debug_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices); -} - @@ -3420,6 +3112,8 @@ void VM_altstr_ins(void) char *out; char outstr[VM_STRINGTEMP_LENGTH]; + VM_SAFEPARMCOUNT(3, VM_altstr_ins); + in = instr = PRVM_G_STRING( OFS_PARM0 ); num = (int)PRVM_G_FLOAT( OFS_PARM1 ); set = setstr = PRVM_G_STRING( OFS_PARM2 ); @@ -3456,6 +3150,7 @@ typedef struct char *strings[MAX_QCSTR_STRINGS]; }qcstrbuffer_t; +// FIXME: move stringbuffers to prog_t to allow multiple progs! static qcstrbuffer_t *qcstringbuffers[MAX_QCSTR_BUFFERS]; static int num_qcstringbuffers; static int buf_sortpower; @@ -3527,21 +3222,6 @@ static int BufStr_SortStringsDOWN (const void *in1, const void *in2) return strncmp(b, a, buf_sortpower); } -#ifdef REMOVETHIS -static void VM_BufStr_Init (void) -{ - memset(qcstringbuffers, 0, sizeof(qcstringbuffers)); - num_qcstringbuffers = 0; -} - -static void VM_BufStr_ShutDown (void) -{ - int i; - for(i=0;iglobaloffsets.self)->edict); if (ent == prog->edicts) { @@ -3973,6 +3655,8 @@ void VM_changepitch (void) prvm_edict_t *ent; float ideal, current, move, speed; + VM_SAFEPARMCOUNT(1, VM_changepitch); + ent = PRVM_G_EDICT(OFS_PARM0); if (ent == prog->edicts) { @@ -4020,6 +3704,122 @@ void VM_changepitch (void) PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.angles)->vector[0] = ANGLEMOD (current + move); } + +static int Is_Text_Color (char c, char t) +{ + int a = 0; + char c2 = c - (c & 128); + char t2 = t - (t & 128); + + if(c != STRING_COLOR_TAG && c2 != STRING_COLOR_TAG) return 0; + if(t >= '0' && t <= '9') a = 1; + if(t2 >= '0' && t2 <= '9') a = 1; +/* if(t >= 'A' && t <= 'Z') a = 2; + if(t2 >= 'A' && t2 <= 'Z') a = 2; + + if(a == 1 && scr_colortext.integer > 0) + return 1; + if(a == 2 && scr_multifonts.integer > 0) + return 2; +*/ + return a; +} + +void VM_uncolorstring (void) +{ + const char *in; + char out[VM_STRINGTEMP_LENGTH]; + int k = 0, i = 0; + + VM_SAFEPARMCOUNT(1, VM_uncolorstring); + in = PRVM_G_STRING(OFS_PARM0); + VM_CheckEmptyString (in); + + while (in[k]) + { + if(in[k+1]) + if(Is_Text_Color(in[k], in[k+1]) == 1/* || (in[k] == '&' && in[k+1] == 'r')*/) + { + k += 2; + continue; + } + out[i] = in[k]; + ++k; + ++i; + } + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(out); +} + +//#222 string(string s, float index) str2chr (FTE_STRINGS) +void VM_str2chr (void) +{ + const char *s; + VM_SAFEPARMCOUNT(2, VM_str2chr); + s = PRVM_G_STRING(OFS_PARM0); + if((unsigned)PRVM_G_FLOAT(OFS_PARM1) > strlen(s)) + return; + PRVM_G_FLOAT(OFS_RETURN) = (unsigned char)s[(int)PRVM_G_FLOAT(OFS_PARM1)]; +} + +//#223 string(float c, ...) chr2str (FTE_STRINGS) +void VM_chr2str (void) +{ + char t[9]; + int i; + VM_SAFEPARMCOUNTRANGE(0, 8, VM_chr2str); + for(i = 0;i < prog->argc && i < (int)sizeof(t) - 1;i++) + t[i] = (unsigned char)PRVM_G_FLOAT(OFS_PARM0+i*3); + t[i] = 0; + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t); +} + +//#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS) +void VM_strncmp (void) +{ + const char *s1, *s2; + VM_SAFEPARMCOUNT(1, VM_strncmp); + s1 = PRVM_G_STRING(OFS_PARM0); + s2 = PRVM_G_STRING(OFS_PARM1); + PRVM_G_FLOAT(OFS_RETURN) = strncmp(s1, s2, (size_t)PRVM_G_FLOAT(OFS_PARM2)); +} + +void VM_wasfreed (void) +{ + VM_SAFEPARMCOUNT(1, VM_wasfreed); + PRVM_G_FLOAT(OFS_RETURN) = PRVM_G_EDICT(OFS_PARM0)->priv.required->free; +} + +void VM_SetTraceGlobals(const trace_t *trace) +{ + prvm_eval_t *val; + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_allsolid))) + val->_float = trace->allsolid; + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_startsolid))) + val->_float = trace->startsolid; + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_fraction))) + val->_float = trace->fraction; + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_inwater))) + val->_float = trace->inwater; + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_inopen))) + val->_float = trace->inopen; + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_endpos))) + VectorCopy(trace->endpos, val->vector); + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_plane_normal))) + VectorCopy(trace->plane.normal, val->vector); + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_plane_dist))) + val->_float = trace->plane.dist; + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_ent))) + val->edict = PRVM_EDICT_TO_PROG(trace->ent ? trace->ent : prog->edicts); + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents))) + val->_float = trace->startsupercontents; + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents))) + val->_float = trace->hitsupercontents; + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags))) + val->_float = trace->hitq3surfaceflags; + if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename))) + val->string = trace->hittexture ? PRVM_SetTempString(trace->hittexture->name) : 0; +} + //============= void VM_Cmd_Init(void) @@ -4028,11 +3828,6 @@ void VM_Cmd_Init(void) VM_Files_Init(); VM_Search_Init(); // VM_BufStr_Init(); - if(vm_polygons_initialized) - { - Mem_FreePool(&vm_polygons_pool); - vm_polygons_initialized = false; - } } void VM_Cmd_Reset(void) @@ -4041,10 +3836,5 @@ void VM_Cmd_Reset(void) VM_Search_Reset(); VM_Files_CloseAll(); // VM_BufStr_ShutDown(); - if(vm_polygons_initialized) - { - Mem_FreePool(&vm_polygons_pool); - vm_polygons_initialized = false; - } }