]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_cmds.c
more redundant suffix elimination
[xonotic/darkplaces.git] / prvm_cmds.c
index e3e1b322dbc1c3bde3c307a4c10a449d886821cc..69db32caaffddbc6e967c4aca295c1e4c9d3a350 100644 (file)
@@ -25,7 +25,7 @@ void VM_Warning(const char *fmt, ...)
        dpvsnprintf(msg,sizeof(msg),fmt,argptr);
        va_end(argptr);
 
-       Con_Print(msg);
+       Con_DPrint(msg);
 
        // TODO: either add a cvar/cmd to control the state dumping or replace some of the calls with Con_Printf [9/13/2006 Black]
        if(prvm_backtraceforwarnings.integer && recursive != realtime) // NOTE: this compares to the time, just in case if PRVM_PrintState causes a Host_Error and keeps recursive set
@@ -744,15 +744,12 @@ void VM_dprint (void)
 {
        char string[VM_STRINGTEMP_LENGTH];
        VM_SAFEPARMCOUNTRANGE(1, 8, VM_dprint);
-       if (developer.integer)
-       {
-               VM_VarString(0, string, sizeof(string));
+       VM_VarString(0, string, sizeof(string));
 #if 1
-               Con_Printf("%s", string);
+       Con_DPrintf("%s", string);
 #else
-               Con_Printf("%s: %s", PRVM_NAME, string);
+       Con_DPrintf("%s: %s", PRVM_NAME, string);
 #endif
-       }
 }
 
 /*
@@ -974,12 +971,12 @@ void VM_remove (void)
        ed = PRVM_G_EDICT(OFS_PARM0);
        if( PRVM_NUM_FOR_EDICT(ed) <= prog->reserved_edicts )
        {
-               if (developer.integer >= 1)
+               if (developer.integer)
                        VM_Warning( "VM_remove: tried to remove the null entity or a reserved entity!\n" );
        }
        else if( ed->priv.required->free )
        {
-               if (developer.integer >= 1)
+               if (developer.integer)
                        VM_Warning( "VM_remove: tried to remove an already freed entity!\n" );
        }
        else
@@ -1845,14 +1842,14 @@ void VM_fopen(void)
        if (prog->openfiles[filenum] == NULL)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -1;
-               if (developer.integer >= 100)
+               if (developer_extra.integer)
                        VM_Warning("VM_fopen: %s: %s mode %s failed\n", PRVM_NAME, filename, modestring);
        }
        else
        {
                PRVM_G_FLOAT(OFS_RETURN) = filenum;
-               if (developer.integer >= 100)
-                       Con_Printf("VM_fopen: %s: %s mode %s opened as #%i\n", PRVM_NAME, filename, modestring, filenum);
+               if (developer_extra.integer)
+                       Con_DPrintf("VM_fopen: %s: %s mode %s opened as #%i\n", PRVM_NAME, filename, modestring, filenum);
                prog->openfiles_origin[filenum] = PRVM_AllocationOrigin();
        }
 }
@@ -1886,8 +1883,8 @@ void VM_fclose(void)
        prog->openfiles[filenum] = NULL;
        if(prog->openfiles_origin[filenum])
                PRVM_Free((char *)prog->openfiles_origin[filenum]);
-       if (developer.integer >= 100)
-               Con_Printf("VM_fclose: %s: #%i closed\n", PRVM_NAME, filenum);
+       if (developer_extra.integer)
+               Con_DPrintf("VM_fclose: %s: #%i closed\n", PRVM_NAME, filenum);
 }
 
 /*
@@ -1937,8 +1934,8 @@ void VM_fgets(void)
                if (c != '\n')
                        FS_UnGetc(prog->openfiles[filenum], (unsigned char)c);
        }
-       if (developer.integer >= 100)
-               Con_Printf("fgets: %s: %s\n", PRVM_NAME, string);
+       if (developer_extra.integer)
+               Con_DPrintf("fgets: %s: %s\n", PRVM_NAME, string);
        if (c >= 0 || end)
                PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
 }
@@ -1973,8 +1970,8 @@ void VM_fputs(void)
        VM_VarString(1, string, sizeof(string));
        if ((stringlength = (int)strlen(string)))
                FS_Write(prog->openfiles[filenum], string, stringlength);
-       if (developer.integer >= 100)
-               Con_Printf("fputs: %s: %s\n", PRVM_NAME, string);
+       if (developer_extra.integer)
+               Con_DPrintf("fputs: %s: %s\n", PRVM_NAME, string);
 }
 
 /*
@@ -3151,8 +3148,6 @@ void VM_chr(void)
        VM_SAFEPARMCOUNT(1, VM_chr);
 
        len = u8_fromchar((Uchar)PRVM_G_FLOAT(OFS_PARM0), tmp, sizeof(tmp));
-       if (len < 0)
-               len = 0;
        tmp[len] = 0;
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(tmp);
 }
@@ -3216,6 +3211,21 @@ void VM_freepic(void)
        Draw_FreePic(s);
 }
 
+void getdrawfontscale(float *sx, float *sy)
+{
+       vec3_t v;
+       *sx = *sy = 1;
+       if(prog->globaloffsets.drawfontscale >= 0)
+       {
+               VectorCopy(PRVM_G_VECTOR(prog->globaloffsets.drawfontscale), v);
+               if(VectorLength2(v) > 0)
+               {
+                       *sx = v[0];
+                       *sy = v[1];
+               }
+       }
+}
+
 dp_font_t *getdrawfont(void)
 {
        if(prog->globaloffsets.drawfont >= 0)
@@ -3241,6 +3251,7 @@ void VM_drawcharacter(void)
        float *pos,*scale,*rgb;
        char   character;
        int flag;
+       float sx, sy;
        VM_SAFEPARMCOUNT(6,VM_drawcharacter);
 
        character = (char) PRVM_G_FLOAT(OFS_PARM1);
@@ -3273,7 +3284,8 @@ void VM_drawcharacter(void)
                return;
        }
 
-       DrawQ_String_Font(pos[0], pos[1], &character, 1, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont());
+       getdrawfontscale(&sx, &sy);
+       DrawQ_String_Scale(pos[0], pos[1], &character, 1, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont());
        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
 
@@ -3289,6 +3301,7 @@ void VM_drawstring(void)
        float *pos,*scale,*rgb;
        const char  *string;
        int flag;
+       float sx, sy;
        VM_SAFEPARMCOUNT(6,VM_drawstring);
 
        string = PRVM_G_STRING(OFS_PARM1);
@@ -3314,7 +3327,8 @@ void VM_drawstring(void)
        if(pos[2] || scale[2])
                Con_Printf("VM_drawstring: z value%s from %s discarded\n",(pos[2] && scale[2]) ? "s" : " ",((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
 
-       DrawQ_String_Font(pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont());
+       getdrawfontscale(&sx, &sy);
+       DrawQ_String_Scale(pos[0], pos[1], string, 0, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont());
        //Font_DrawString(pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true);
        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
@@ -3331,6 +3345,7 @@ void VM_drawcolorcodedstring(void)
        float *pos,*scale;
        const char  *string;
        int flag,color;
+       float sx, sy;
        VM_SAFEPARMCOUNT(5,VM_drawstring);
 
        string = PRVM_G_STRING(OFS_PARM1);
@@ -3356,7 +3371,8 @@ void VM_drawcolorcodedstring(void)
                Con_Printf("VM_drawcolorcodedstring: z value%s from %s discarded\n",(pos[2] && scale[2]) ? "s" : " ",((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
 
        color = -1;
-       DrawQ_String_Font(pos[0], pos[1], string, 0, scale[0], scale[1], 1, 1, 1, PRVM_G_FLOAT(OFS_PARM3), flag, NULL, false, getdrawfont());
+       getdrawfontscale(&sx, &sy);
+       DrawQ_String_Scale(pos[0], pos[1], string, 0, scale[0], scale[1], sx, sy, 1, 1, 1, PRVM_G_FLOAT(OFS_PARM3), flag, NULL, false, getdrawfont());
        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
 /*
@@ -3372,9 +3388,11 @@ void VM_stringwidth(void)
        float *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 x[200];
+       float sx, sy;
+       size_t maxlen = 0;
        VM_SAFEPARMCOUNTRANGE(2,3,VM_drawstring);
 
+       getdrawfontscale(&sx, &sy);
        if(prog->argc == 3)
        {
                szv = PRVM_G_VECTOR(OFS_PARM2);
@@ -3382,16 +3400,23 @@ void VM_stringwidth(void)
        }
        else
        {
-               static float defsize[] = {0, 0};
+               // we want the width for 8x8 font size, divided by 8
+               static float defsize[] = {8, 8};
                szv = defsize;
-               mult = 1;
+               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)
+               {
+                       mult *= 2;
+                       sx /= 2;
+                       sy /= 2;
+               }
        }
-       x[180] = 3;
 
        string = PRVM_G_STRING(OFS_PARM0);
        colors = (int)PRVM_G_FLOAT(OFS_PARM1);
 
-       PRVM_G_FLOAT(OFS_RETURN) = DrawQ_TextWidth_Font_Size(string, szv[0], szv[1], 0, !colors, getdrawfont()) * mult; // 1x1 characters, don't actually draw
+       PRVM_G_FLOAT(OFS_RETURN) = DrawQ_TextWidth_UntilWidth_TrackColors_Scale(string, &maxlen, szv[0], szv[1], sx, sy, NULL, !colors, getdrawfont(), 1000000000) * mult;
 /*
        if(prog->argc == 3)
        {
@@ -3406,7 +3431,7 @@ void VM_stringwidth(void)
        string = PRVM_G_STRING(OFS_PARM0);
        colors = (int)PRVM_G_FLOAT(OFS_PARM1);
 
-       PRVM_G_FLOAT(OFS_RETURN) = DrawQ_TextWidth_Font(string, 0, !colors, getdrawfont()) * mult; // 1x1 characters, don't actually draw
+       PRVM_G_FLOAT(OFS_RETURN) = DrawQ_TextWidth(string, 0, !colors, getdrawfont()) * mult; // 1x1 characters, don't actually draw
 */
 
 }
@@ -5032,7 +5057,7 @@ void VM_str2chr (void)
 
        if((unsigned)index < strlen(s))
        {
-               ch = u8_getchar(s + index, NULL);
+               ch = u8_getchar_noendptr(s + index);
                PRVM_G_FLOAT(OFS_RETURN) = ch;
        }
        else
@@ -5056,11 +5081,7 @@ void VM_chr2str (void)
        size_t len = 0;
        VM_SAFEPARMCOUNTRANGE(0, 8, VM_chr2str);
        for(i = 0; i < prog->argc && len < sizeof(t)-1; ++i)
-       {
-               int add = u8_fromchar((Uchar)PRVM_G_FLOAT(OFS_PARM0+i*3), t + len, sizeof(t)-1);
-               if(add > 0)
-                       len += add;
-       }
+               len += u8_fromchar((Uchar)PRVM_G_FLOAT(OFS_PARM0+i*3), t + len, sizeof(t)-1);
        t[len] = 0;
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
 }
@@ -5666,3 +5687,265 @@ void VM_isfunction(void)
        else
                PRVM_G_FLOAT(OFS_RETURN) = true;
 }
+
+/*
+=========
+VM_sprintf
+
+string sprintf(string format, ...)
+=========
+*/
+
+void VM_sprintf(void)
+{
+       const char *s, *s0;
+       char outbuf[MAX_INPUTLINE];
+       char *o = outbuf, *end = outbuf + sizeof(outbuf), *err;
+       int argpos = 1;
+       int width, precision, thisarg, flags;
+       char formatbuf[16];
+       char *f;
+       qboolean isfloat;
+#define PRINTF_ALTERNATE 1
+#define PRINTF_ZEROPAD 2
+#define PRINTF_LEFT 4
+#define PRINTF_SPACEPOSITIVE 8
+#define PRINTF_SIGNPOSITIVE 16
+
+       formatbuf[0] = '%';
+
+       s = PRVM_G_STRING(OFS_PARM0);
+
+#define GETARG_FLOAT(a) (((a)>=1 && (a)<prog->argc) ? (PRVM_G_FLOAT(OFS_PARM0 + 3 * (a))) : 0)
+#define GETARG_INT(a) (((a)>=1 && (a)<prog->argc) ? (PRVM_G_INT(OFS_PARM0 + 3 * (a))) : 0)
+#define GETARG_STRING(a) (((a)>=1 && (a)<prog->argc) ? (PRVM_G_STRING(OFS_PARM0 + 3 * (a))) : "")
+
+       for(;;)
+       {
+               s0 = s;
+               switch(*s)
+               {
+                       case 0:
+                               goto finished;
+                               break;
+                       case '%':
+                               ++s;
+
+                               if(*s == '%')
+                                       goto verbatim;
+
+                               // complete directive format:
+                               // %3$*1$.*2$ld
+                               
+                               width = -1;
+                               precision = -1;
+                               thisarg = -1;
+                               flags = 0;
+
+                               // is number following?
+                               if(*s >= '0' && *s <= '9')
+                               {
+                                       width = strtol(s, &err, 10);
+                                       if(!err)
+                                       {
+                                               VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                               goto finished;
+                                       }
+                                       if(*err == '$')
+                                       {
+                                               thisarg = width;
+                                               width = -1;
+                                               s = err + 1;
+                                       }
+                                       else
+                                       {
+                                               if(*s == '0')
+                                               {
+                                                       flags |= PRINTF_ZEROPAD;
+                                                       if(width == 0)
+                                                               width = -1; // it was just a flag
+                                               }
+                                               s = err;
+                                       }
+                               }
+
+                               if(width < 0)
+                               {
+                                       for(;;)
+                                       {
+                                               switch(*s)
+                                               {
+                                                       case '#': flags |= PRINTF_ALTERNATE; break;
+                                                       case '0': flags |= PRINTF_ZEROPAD; break;
+                                                       case '-': flags |= PRINTF_LEFT; break;
+                                                       case ' ': flags |= PRINTF_SPACEPOSITIVE; break;
+                                                       case '+': flags |= PRINTF_SIGNPOSITIVE; break;
+                                                       default:
+                                                               goto noflags;
+                                               }
+                                               ++s;
+                                       }
+noflags:
+                                       if(*s == '*')
+                                       {
+                                               ++s;
+                                               if(*s >= '0' && *s <= '9')
+                                               {
+                                                       width = strtol(s, &err, 10);
+                                                       if(!err || *err != '$')
+                                                       {
+                                                               VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                                               goto finished;
+                                                       }
+                                                       s = err + 1;
+                                               }
+                                               else
+                                                       width = argpos++;
+                                               width = GETARG_FLOAT(width);
+                                       }
+                                       else if(*s >= '0' && *s <= '9')
+                                       {
+                                               width = strtol(s, &err, 10);
+                                               if(!err)
+                                               {
+                                                       VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                                       goto finished;
+                                               }
+                                               s = err;
+                                       }
+                                       if(width < 0)
+                                       {
+                                               flags |= PRINTF_LEFT;
+                                               width = -width;
+                                       }
+                               }
+
+                               if(*s == '.')
+                               {
+                                       ++s;
+                                       if(*s == '*')
+                                       {
+                                               ++s;
+                                               if(*s >= '0' && *s <= '9')
+                                               {
+                                                       precision = strtol(s, &err, 10);
+                                                       if(!err || *err != '$')
+                                                       {
+                                                               VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                                               goto finished;
+                                                       }
+                                                       s = err + 1;
+                                               }
+                                               else
+                                                       precision = argpos++;
+                                               precision = GETARG_FLOAT(precision);
+                                       }
+                                       else if(*s >= '0' && *s <= '9')
+                                       {
+                                               precision = strtol(s, &err, 10);
+                                               if(!err)
+                                               {
+                                                       VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                                       goto finished;
+                                               }
+                                               s = err;
+                                       }
+                                       else
+                                       {
+                                               VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                               goto finished;
+                                       }
+                               }
+
+                               isfloat = true;
+                               for(;;)
+                               {
+                                       switch(*s)
+                                       {
+                                               case 'h': isfloat = true; break;
+                                               case 'l': isfloat = false; break;
+                                               case 'L': isfloat = false; break;
+                                               case 'j': break;
+                                               case 'z': break;
+                                               case 't': break;
+                                               default:
+                                                       goto nolength;
+                                       }
+                                       ++s;
+                               }
+nolength:
+
+                               if(thisarg < 0)
+                                       thisarg = argpos++;
+
+                               if(o < end - 1)
+                               {
+                                       f = &formatbuf[1];
+                                       if(*s != 's' && *s != 'c')
+                                               if(flags & PRINTF_ALTERNATE) *f++ = '#';
+                                       if(flags & PRINTF_ZEROPAD) *f++ = '0';
+                                       if(flags & PRINTF_LEFT) *f++ = '-';
+                                       if(flags & PRINTF_SPACEPOSITIVE) *f++ = ' ';
+                                       if(flags & PRINTF_SIGNPOSITIVE) *f++ = '+';
+                                       *f++ = '*';
+                                       *f++ = '.';
+                                       *f++ = '*';
+                                       *f++ = *s;
+                                       *f++ = 0;
+
+                                       if(width < 0)
+                                               width = 0;
+
+                                       switch(*s)
+                                       {
+                                               case 'd': case 'i':
+                                                       o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (int) GETARG_FLOAT(thisarg) : (int) GETARG_INT(thisarg)));
+                                                       break;
+                                               case 'o': case 'u': case 'x': case 'X':
+                                                       o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg)));
+                                                       break;
+                                               case 'e': case 'E': case 'f': case 'F': case 'g': case 'G':
+                                                       if(precision < 0)
+                                                               precision = 6;
+                                                       o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (double) GETARG_FLOAT(thisarg) : (double) GETARG_INT(thisarg)));
+                                                       break;
+                                               case 'c':
+                                                       if(precision < 0)
+                                                               precision = end - o - 1;
+                                                       if(flags & PRINTF_ALTERNATE)
+                                                               o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg)));
+                                                       else
+                                                       {
+                                                               unsigned int c = (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg));
+                                                               const char *buf = u8_encodech(c, NULL);
+                                                               if(!buf)
+                                                                       buf = "";
+                                                               o += u8_strpad(o, end - o, buf, (flags & PRINTF_LEFT) != 0, width, precision);
+                                                       }
+                                                       break;
+                                               case 's':
+                                                       if(precision < 0)
+                                                               precision = end - o - 1;
+                                                       if(flags & PRINTF_ALTERNATE)
+                                                               o += dpsnprintf(o, end - o, formatbuf, width, precision, GETARG_STRING(thisarg));
+                                                       else
+                                                               o += u8_strpad(o, end - o, GETARG_STRING(thisarg), (flags & PRINTF_LEFT) != 0, width, precision);
+                                                       break;
+                                               default:
+                                                       VM_Warning("VM_sprintf: invalid directive in %s: %s\n", PRVM_NAME, s0);
+                                                       goto finished;
+                                       }
+                               }
+                               ++s;
+                               break;
+                       default:
+verbatim:
+                               if(o < end - 1)
+                                       *o++ = *s++;
+                               break;
+               }
+       }
+finished:
+       *o = 0;
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(outbuf);
+}