]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_cmds.c
Revert "Make cdda optional, server does not need to play music" because it
[xonotic/darkplaces.git] / prvm_cmds.c
index f62583115eff0a82393ae8fb8da16d1738035109..1c9c8099b7c26fcb03b9981561b6cdd81f86e60c 100644 (file)
@@ -17,7 +17,9 @@
 #include "mdfour.h"
 
 extern cvar_t prvm_backtraceforwarnings;
+#ifdef USEODE
 extern dllhandle_t ode_dll;
+#endif
 
 // LordHavoc: changed this to NOT use a return statement, so that it can be used in functions that must return a value
 void VM_Warning(prvm_prog_t *prog, const char *fmt, ...)
@@ -36,7 +38,7 @@ void VM_Warning(prvm_prog_t *prog, const char *fmt, ...)
        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
        {
                recursive = realtime;
-               PRVM_PrintState(prog);
+               PRVM_PrintState(prog, 0);
                recursive = -1;
        }
 }
@@ -275,19 +277,21 @@ static qboolean checkextension(prvm_prog_t *prog, const char *name)
                        e++;
                if ((e - start) == len && !strncasecmp(start, name, len))
                {
+#ifdef USEODE
                        // special sheck for ODE
                        if (!strncasecmp("DP_PHYSICS_ODE", name, 14))
                        {
-#ifdef ODE_DYNAMIC
+#ifndef LINK_TO_LIBODE
                                return ode_dll ? true : false;
 #else
-#ifdef ODE_STATIC
+#ifdef LINK_TO_LIBODE
                                return true;
 #else
                                return false;
 #endif
 #endif
                        }
+#endif
 
                        // special sheck for d0_blind_id
                        if (!strcasecmp("DP_CRYPTO", name))
@@ -777,15 +781,15 @@ string    ftos(float)
 
 void VM_ftos(prvm_prog_t *prog)
 {
-       float v;
+       prvm_vec_t v;
        char s[128];
 
        VM_SAFEPARMCOUNT(1, VM_ftos);
 
        v = PRVM_G_FLOAT(OFS_PARM0);
 
-       if ((float)((int)v) == v)
-               dpsnprintf(s, sizeof(s), "%i", (int)v);
+       if ((prvm_vec_t)((prvm_int_t)v) == v)
+               dpsnprintf(s, sizeof(s), "%.0f", v);
        else
                dpsnprintf(s, sizeof(s), "%f", v);
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, s);
@@ -801,7 +805,7 @@ float       fabs(float)
 
 void VM_fabs(prvm_prog_t *prog)
 {
-       float   v;
+       prvm_vec_t v;
 
        VM_SAFEPARMCOUNT(1,VM_fabs);
 
@@ -864,7 +868,7 @@ void VM_stof(prvm_prog_t *prog)
 ========================
 VM_itof
 
-float itof(intt ent)
+float itof(int ent)
 ========================
 */
 void VM_itof(prvm_prog_t *prog)
@@ -882,10 +886,10 @@ entity ftoe(float num)
 */
 void VM_ftoe(prvm_prog_t *prog)
 {
-       int ent;
+       prvm_int_t ent;
        VM_SAFEPARMCOUNT(1, VM_ftoe);
 
-       ent = (int)PRVM_G_FLOAT(OFS_PARM0);
+       ent = (prvm_int_t)PRVM_G_FLOAT(OFS_PARM0);
        if (ent < 0 || ent >= prog->max_edicts || PRVM_PROG_TO_EDICT(ent)->priv.required->free)
                ent = 0; // return world instead of a free or invalid entity
 
@@ -1192,9 +1196,9 @@ entity    findflags(entity start, .float field, float match)
 // LordHavoc: search for flags in float fields
 void VM_findflags(prvm_prog_t *prog)
 {
-       int             e;
-       int             f;
-       int             s;
+       prvm_int_t      e;
+       prvm_int_t      f;
+       prvm_int_t      s;
        prvm_edict_t    *ed;
 
        VM_SAFEPARMCOUNT(3, VM_findflags);
@@ -1202,7 +1206,7 @@ void VM_findflags(prvm_prog_t *prog)
 
        e = PRVM_G_EDICTNUM(OFS_PARM0);
        f = PRVM_G_INT(OFS_PARM1);
-       s = (int)PRVM_G_FLOAT(OFS_PARM2);
+       s = (prvm_int_t)PRVM_G_FLOAT(OFS_PARM2);
 
        for (e++ ; e < prog->num_edicts ; e++)
        {
@@ -1212,7 +1216,7 @@ void VM_findflags(prvm_prog_t *prog)
                        continue;
                if (!PRVM_E_FLOAT(ed,f))
                        continue;
-               if ((int)PRVM_E_FLOAT(ed,f) & s)
+               if ((prvm_int_t)PRVM_E_FLOAT(ed,f) & s)
                {
                        VM_RETURN_EDICT(ed);
                        return;
@@ -1232,9 +1236,9 @@ entity    findchainflags(.float field, float match)
 // LordHavoc: chained search for flags in float fields
 void VM_findchainflags(prvm_prog_t *prog)
 {
-       int             i;
-       int             f;
-       int             s;
+       prvm_int_t              i;
+       prvm_int_t              f;
+       prvm_int_t              s;
        prvm_edict_t    *ent, *chain;
        int chainfield;
 
@@ -1250,7 +1254,7 @@ void VM_findchainflags(prvm_prog_t *prog)
        chain = (prvm_edict_t *)prog->edicts;
 
        f = PRVM_G_INT(OFS_PARM0);
-       s = (int)PRVM_G_FLOAT(OFS_PARM1);
+       s = (prvm_int_t)PRVM_G_FLOAT(OFS_PARM1);
 
        ent = PRVM_NEXT_EDICT(prog->edicts);
        for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
@@ -1260,7 +1264,7 @@ void VM_findchainflags(prvm_prog_t *prog)
                        continue;
                if (!PRVM_E_FLOAT(ent,f))
                        continue;
-               if (!((int)PRVM_E_FLOAT(ent,f) & s))
+               if (!((prvm_int_t)PRVM_E_FLOAT(ent,f) & s))
                        continue;
 
                PRVM_EDICTFIELDEDICT(ent,chainfield) = PRVM_EDICT_TO_PROG(chain);
@@ -1406,7 +1410,7 @@ float     rint(float)
 */
 void VM_rint(prvm_prog_t *prog)
 {
-       float f;
+       prvm_vec_t f;
        VM_SAFEPARMCOUNT(1,VM_rint);
 
        f = PRVM_G_FLOAT(OFS_PARM0);
@@ -2029,14 +2033,14 @@ void VM_entityfieldname(prvm_prog_t *prog)
 {
        ddef_t *d;
        int i = (int)PRVM_G_FLOAT(OFS_PARM0);
-       
+
        if (i < 0 || i >= prog->numfielddefs)
        {
-        VM_Warning(prog, "VM_entityfieldname: %s: field index out of bounds\n", prog->name);
-        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "");
+               VM_Warning(prog, "VM_entityfieldname: %s: field index out of bounds\n", prog->name);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "");
                return;
        }
-       
+
        d = &prog->fielddefs[i];
        PRVM_G_INT(OFS_RETURN) = d->s_name; // presuming that s_name points to a string already
 }
@@ -2062,7 +2066,7 @@ void VM_entityfieldtype(prvm_prog_t *prog)
        }
        
        d = &prog->fielddefs[i];
-       PRVM_G_FLOAT(OFS_RETURN) = (float)d->type;
+       PRVM_G_FLOAT(OFS_RETURN) = (prvm_vec_t)d->type;
 }
 
 // KrimZon - DP_QC_ENTITYDATA
@@ -2877,7 +2881,7 @@ void VM_gettime(prvm_prog_t *prog)
 
        if(prog->argc == 0)
        {
-               PRVM_G_FLOAT(OFS_RETURN) = (float) realtime;
+               PRVM_G_FLOAT(OFS_RETURN) = (prvm_vec_t) realtime;
        }
        else
        {
@@ -2934,7 +2938,7 @@ void VM_getsoundtime (prvm_prog_t *prog)
        entchannel = CHAN_USER2ENGINE(entchannel);
        if (!IS_CHAN(entchannel))
                VM_Warning(prog, "VM_getsoundtime: %s: bad channel %i\n", prog->name, entchannel);
-       PRVM_G_FLOAT(OFS_RETURN) = (float)S_GetEntChannelPosition(entnum, entchannel);
+       PRVM_G_FLOAT(OFS_RETURN) = (prvm_vec_t)S_GetEntChannelPosition(entnum, entchannel);
 }
 
 /*
@@ -3039,13 +3043,13 @@ float   mod(float val, float m)
 */
 void VM_modulo(prvm_prog_t *prog)
 {
-       int val, m;
+       prvm_int_t val, m;
        VM_SAFEPARMCOUNT(2,VM_module);
 
-       val = (int) PRVM_G_FLOAT(OFS_PARM0);
-       m       = (int) PRVM_G_FLOAT(OFS_PARM1);
+       val = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM0);
+       m       = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM1);
 
-       PRVM_G_FLOAT(OFS_RETURN) = (float) (val % m);
+       PRVM_G_FLOAT(OFS_RETURN) = (prvm_vec_t) (val % m);
 }
 
 static void VM_Search_Init(prvm_prog_t *prog)
@@ -4360,11 +4364,11 @@ void VM_drawline (prvm_prog_t *prog)
 // float(float number, float quantity) bitshift (EXT_BITSHIFT)
 void VM_bitshift (prvm_prog_t *prog)
 {
-       int n1, n2;
+       prvm_int_t n1, n2;
        VM_SAFEPARMCOUNT(2, VM_bitshift);
 
-       n1 = (int)fabs((float)((int)PRVM_G_FLOAT(OFS_PARM0)));
-       n2 = (int)PRVM_G_FLOAT(OFS_PARM1);
+       n1 = (prvm_int_t)fabs((prvm_vec_t)((prvm_int_t)PRVM_G_FLOAT(OFS_PARM0)));
+       n2 = (prvm_int_t)PRVM_G_FLOAT(OFS_PARM1);
        if(!n1)
                PRVM_G_FLOAT(OFS_RETURN) = n1;
        else
@@ -4405,7 +4409,7 @@ void VM_altstr_count(prvm_prog_t *prog)
                }
        }
 
-       PRVM_G_FLOAT( OFS_RETURN ) = (float) (count / 2);
+       PRVM_G_FLOAT( OFS_RETURN ) = (prvm_vec_t) (count / 2);
 }
 
 /*
@@ -4629,6 +4633,94 @@ 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 *stringbuffer;
+       int i;
+
+       if (bufindex < 0)
+               return NULL;
+
+       // find buffer with wanted index
+       if (bufindex < (int)Mem_ExpandableArray_IndexRange(&prog->stringbuffersarray))
+       {
+               if ( (stringbuffer = (prvm_stringbuffer_t*) Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, bufindex)) )
+               {
+                       if (stringbuffer->flags & STRINGBUFFER_TEMP)
+                               stringbuffer->flags = flags; // created but has not been used yet
+                       return stringbuffer;
+               }
+               return NULL;
+       }
+
+       // allocate new buffer with wanted index
+       while(1)
+       {
+               stringbuffer = (prvm_stringbuffer_t *) Mem_ExpandableArray_AllocRecord(&prog->stringbuffersarray);
+               stringbuffer->flags = STRINGBUFFER_TEMP;
+               for (i = 0;stringbuffer != Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i);i++);
+               if (i == bufindex)
+               {
+                       stringbuffer->flags = flags; // mark as used
+                       break;
+               }
+       }
+       return stringbuffer;
+}
+
+void BufStr_Set(prvm_prog_t *prog, prvm_stringbuffer_t *stringbuffer, int strindex, const char *str)
+{
+       size_t  alloclen;
+
+       if (!stringbuffer || strindex < 0)
+               return;
+
+       BufStr_Expand(prog, stringbuffer, strindex);
+       stringbuffer->num_strings = max(stringbuffer->num_strings, strindex + 1);
+       if (stringbuffer->strings[strindex])
+               Mem_Free(stringbuffer->strings[strindex]);
+       stringbuffer->strings[strindex] = NULL;
+
+       if (str)
+       {
+               // not the NULL string!
+               alloclen = strlen(str) + 1;
+               stringbuffer->strings[strindex] = (char *)Mem_Alloc(prog->progs_mempool, alloclen);
+               memcpy(stringbuffer->strings[strindex], str, alloclen);
+       }
+
+       BufStr_Shrink(prog, stringbuffer);
+}
+
+void BufStr_Del(prvm_prog_t *prog, prvm_stringbuffer_t *stringbuffer)
+{
+       int i;
+       
+       if (!stringbuffer)
+               return;
+
+       for (i = 0;i < stringbuffer->num_strings;i++)
+               if (stringbuffer->strings[i])
+                       Mem_Free(stringbuffer->strings[i]);
+       if (stringbuffer->strings)
+               Mem_Free(stringbuffer->strings);
+       if(stringbuffer->origin)
+               PRVM_Free((char *)stringbuffer->origin);
+       Mem_ExpandableArray_FreeRecord(&prog->stringbuffersarray, stringbuffer);
+}
+
+void BufStr_Flush(prvm_prog_t *prog)
+{
+       prvm_stringbuffer_t *stringbuffer;
+       int i, numbuffers;
+
+       numbuffers = Mem_ExpandableArray_IndexRange(&prog->stringbuffersarray);
+       for (i = 0; i < numbuffers; i++)
+               if ( (stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i)) )
+                       BufStr_Del(prog, stringbuffer);
+       Mem_ExpandableArray_NewArray(&prog->stringbuffersarray, prog->progs_mempool, sizeof(prvm_stringbuffer_t), 64);
+}
+
 /*
 ========================
 VM_buf_create
@@ -4656,7 +4748,7 @@ void VM_buf_create (prvm_prog_t *prog)
        stringbuffer->origin = PRVM_AllocationOrigin(prog);
        // optional flags parm
        if (prog->argc >= 2)
-               stringbuffer->flags = (int)PRVM_G_FLOAT(OFS_PARM1) & 0xFF;
+               stringbuffer->flags = (int)PRVM_G_FLOAT(OFS_PARM1) & STRINGBUFFER_QCFLAGS;
        PRVM_G_FLOAT(OFS_RETURN) = i;
 }
 
@@ -4675,17 +4767,7 @@ void VM_buf_del (prvm_prog_t *prog)
        VM_SAFEPARMCOUNT(1, VM_buf_del);
        stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
        if (stringbuffer)
-       {
-               int i;
-               for (i = 0;i < stringbuffer->num_strings;i++)
-                       if (stringbuffer->strings[i])
-                               Mem_Free(stringbuffer->strings[i]);
-               if (stringbuffer->strings)
-                       Mem_Free(stringbuffer->strings);
-               if(stringbuffer->origin)
-                       PRVM_Free((char *)stringbuffer->origin);
-               Mem_ExpandableArray_FreeRecord(&prog->stringbuffersarray, stringbuffer);
-       }
+               BufStr_Del(prog, stringbuffer);
        else
        {
                VM_Warning(prog, "VM_buf_del: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), prog->name);
@@ -4885,7 +4967,6 @@ void bufstr_set(float bufhandle, float string_index, string str) = #466;
 */
 void VM_bufstr_set (prvm_prog_t *prog)
 {
-       size_t alloclen;
        int                             strindex;
        prvm_stringbuffer_t *stringbuffer;
        const char              *news;
@@ -4905,23 +4986,8 @@ void VM_bufstr_set (prvm_prog_t *prog)
                return;
        }
 
-       BufStr_Expand(prog, stringbuffer, strindex);
-       stringbuffer->num_strings = max(stringbuffer->num_strings, strindex + 1);
-
-       if(stringbuffer->strings[strindex])
-               Mem_Free(stringbuffer->strings[strindex]);
-       stringbuffer->strings[strindex] = NULL;
-
-       if(PRVM_G_INT(OFS_PARM2))
-       {
-               // 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);
-       }
-
-       BufStr_Shrink(prog, stringbuffer);
+       news = PRVM_G_STRING(OFS_PARM2);
+       BufStr_Set(prog, stringbuffer, strindex, news);
 }
 
 /*
@@ -6075,6 +6141,7 @@ typedef struct
        double starttime;
        float id;
        char buffer[MAX_INPUTLINE];
+       char posttype[128];
        unsigned char *postdata; // free when uri_to_prog_t is freed
        size_t postlen;
        char *sigdata; // free when uri_to_prog_t is freed
@@ -6234,7 +6301,8 @@ void VM_uri_get (prvm_prog_t *prog)
                        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);
+               strlcpy(handle->posttype, posttype, sizeof(handle->posttype));
+               ret = Curl_Begin_ToMemory_POST(url, handle->sigdata, 0, handle->posttype, handle->postdata, handle->postlen, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle);
        }
        else
        {
@@ -6433,6 +6501,7 @@ void VM_sprintf(prvm_prog_t *prog)
        const char *s, *s0;
        char outbuf[MAX_INPUTLINE];
        char *o = outbuf, *end = outbuf + sizeof(outbuf), *err;
+       const char *p;
        int argpos = 1;
        int width, precision, thisarg, flags;
        char formatbuf[16];
@@ -6645,6 +6714,12 @@ nolength:
                                                *f++ = '.';
                                                *f++ = '*';
                                        }
+                                       if(*s == 'd' || *s == 'i' || *s == 'o' || *s == 'u' || *s == 'x' || *s == 'X')
+                                       {
+                                               // make it use a good integer type
+                                               for(p = INT_LOSSLESS_FORMAT_SIZE; *p; )
+                                                       *f++ = *p++;
+                                       }
                                        *f++ = *s;
                                        *f++ = 0;
 
@@ -6655,15 +6730,15 @@ nolength:
                                        {
                                                case 'd': case 'i':
                                                        if(precision < 0) // not set
-                                                               o += dpsnprintf(o, end - o, formatbuf, width, (isfloat ? (int) GETARG_FLOAT(thisarg) : (int) GETARG_INT(thisarg)));
+                                                               o += dpsnprintf(o, end - o, formatbuf, width, (isfloat ? INT_LOSSLESS_FORMAT_CONVERT_S(GETARG_FLOAT(thisarg)) : INT_LOSSLESS_FORMAT_CONVERT_S(GETARG_INT(thisarg))));
                                                        else
-                                                               o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (int) GETARG_FLOAT(thisarg) : (int) GETARG_INT(thisarg)));
+                                                               o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? INT_LOSSLESS_FORMAT_CONVERT_S(GETARG_FLOAT(thisarg)) : INT_LOSSLESS_FORMAT_CONVERT_S(GETARG_INT(thisarg))));
                                                        break;
                                                case 'o': case 'u': case 'x': case 'X':
                                                        if(precision < 0) // not set
-                                                               o += dpsnprintf(o, end - o, formatbuf, width, (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg)));
+                                                               o += dpsnprintf(o, end - o, formatbuf, width, (isfloat ? INT_LOSSLESS_FORMAT_CONVERT_U(GETARG_FLOAT(thisarg)) : INT_LOSSLESS_FORMAT_CONVERT_U(GETARG_INT(thisarg))));
                                                        else
-                                                               o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg)));
+                                                               o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? INT_LOSSLESS_FORMAT_CONVERT_U(GETARG_FLOAT(thisarg)) : INT_LOSSLESS_FORMAT_CONVERT_U(GETARG_INT(thisarg))));
                                                        break;
                                                case 'e': case 'E': case 'f': case 'F': case 'g': case 'G':
                                                        if(precision < 0) // not set