]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_cmds.c
allow saving multiplayer games from the menu, rather than refusing
[xonotic/darkplaces.git] / prvm_cmds.c
index 48184e519169af58496829b94490ea17e18193e2..55caaa57879699451ca00d6e9c87889eec720dbe 100644 (file)
@@ -2878,6 +2878,50 @@ void VM_gettime(void)
        }
 }
 
+/*
+=========
+VM_getsoundtime
+
+float  getsoundtime(void)
+=========
+*/
+
+void VM_getsoundtime (void)
+{
+       int entnum, entchannel, pnum;
+       VM_SAFEPARMCOUNT(2,VM_getsoundtime);
+
+       pnum = PRVM_GetProgNr();
+       if (pnum == PRVM_MENUPROG)
+       {
+               VM_Warning("VM_getsoundtime: %s: not supported on this progs\n", PRVM_NAME);
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
+               return;
+       }
+       entnum = ((pnum == PRVM_CLIENTPROG) ? MAX_EDICTS : 0) + PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0));
+       entchannel = (int)PRVM_G_FLOAT(OFS_PARM1);
+       if (entchannel <= 0 || entchannel > 8)
+               VM_Warning("VM_getsoundtime: %s: bad channel %i\n", PRVM_NAME, entchannel);
+       PRVM_G_FLOAT(OFS_RETURN) = (float)S_GetEntChannelPosition(entnum, entchannel);
+}
+
+/*
+=========
+VM_GetSoundLen
+
+string soundlength (string sample)
+=========
+*/
+void VM_soundlength (void)
+{
+       const char *s;
+
+       VM_SAFEPARMCOUNT(1, VM_soundlength);
+
+       s = PRVM_G_STRING(OFS_PARM0);
+       PRVM_G_FLOAT(OFS_RETURN) = S_SoundLength(s);
+}
+
 /*
 =========
 VM_loadfromdata
@@ -4439,19 +4483,34 @@ static int BufStr_SortStringsDOWN (const void *in1, const void *in2)
 VM_buf_create
 creates new buffer, and returns it's index, returns -1 if failed
 float buf_create(void) = #460;
+float newbuf(string format, float flags) = #460;
 ========================
 */
+
 void VM_buf_create (void)
 {
        prvm_stringbuffer_t *stringbuffer;
        int i;
-       VM_SAFEPARMCOUNT(0, VM_buf_create);
+       
+       VM_SAFEPARMCOUNTRANGE(0, 2, VM_buf_create);
+
+       // VorteX: optional parm1 (buffer format) is unfinished, to keep intact with future databuffers extension must be set to "string"
+       if(prog->argc >= 1 && strcmp(PRVM_G_STRING(OFS_PARM0), "string"))
+       {
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
+               return;
+       }
        stringbuffer = (prvm_stringbuffer_t *) Mem_ExpandableArray_AllocRecord(&prog->stringbuffersarray);
        for (i = 0;stringbuffer != Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i);i++);
        stringbuffer->origin = PRVM_AllocationOrigin();
+       // optional flags parm
+       if(prog->argc == 2)
+               stringbuffer->flags = (int)PRVM_G_FLOAT(OFS_PARM1) & 0xFF;
        PRVM_G_FLOAT(OFS_RETURN) = i;
 }
 
+
+
 /*
 ========================
 VM_buf_del
@@ -5041,7 +5100,7 @@ void VM_strstrofs (void)
        if (!match)
                PRVM_G_FLOAT(OFS_RETURN) = -1;
        else
-               PRVM_G_FLOAT(OFS_RETURN) = match - instr;
+               PRVM_G_FLOAT(OFS_RETURN) = u8_strnlen(instr, match-instr);
 }
 
 //#222 string(string s, float index) str2chr (FTE_STRINGS)
@@ -5424,7 +5483,7 @@ void VM_uri_escape (void)
                        || (*p >= 'a' && *p <= 'z')
                        || (*p >= '0' && *p <= '9')
                        || (*p == '-')  || (*p == '_') || (*p == '.')
-                       || (*p == '!')  || (*p == '~') || (*p == '*')
+                       || (*p == '!')  || (*p == '~')
                        || (*p == '\'') || (*p == '(') || (*p == ')'))
                        *q++ = *p;
                else
@@ -5558,7 +5617,7 @@ void VM_uri_get (void)
        handle->prognr = PRVM_GetProgNr();
        handle->starttime = prog->starttime;
        handle->id = id;
-       ret = Curl_Begin_ToMemory(url, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle);
+       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;
@@ -5708,6 +5767,9 @@ void VM_sprintf(void)
        char formatbuf[16];
        char *f;
        qboolean isfloat;
+       static int dummyivec[3] = {0, 0, 0};
+       static float dummyvec[3] = {0, 0, 0};
+
 #define PRINTF_ALTERNATE 1
 #define PRINTF_ZEROPAD 2
 #define PRINTF_LEFT 4
@@ -5719,7 +5781,9 @@ void VM_sprintf(void)
        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_VECTOR(a) (((a)>=1 && (a)<prog->argc) ? (PRVM_G_VECTOR(OFS_PARM0 + 3 * (a))) : dummyvec)
 #define GETARG_INT(a) (((a)>=1 && (a)<prog->argc) ? (PRVM_G_INT(OFS_PARM0 + 3 * (a))) : 0)
+#define GETARG_INTVECTOR(a) (((a)>=1 && (a)<prog->argc) ? ((int*) PRVM_G_VECTOR(OFS_PARM0 + 3 * (a))) : dummyivec)
 #define GETARG_STRING(a) (((a)>=1 && (a)<prog->argc) ? (PRVM_G_STRING(OFS_PARM0 + 3 * (a))) : "")
 
        for(;;)
@@ -5920,6 +5984,16 @@ nolength:
                                                                precision = 6;
                                                        o += dpsnprintf(o, end - o, formatbuf, width, precision, (isfloat ? (double) GETARG_FLOAT(thisarg) : (double) GETARG_INT(thisarg)));
                                                        break;
+                                               case 'v': case 'V':
+                                                       f[-2] += 'g' - 'v';
+                                                       if(precision < 0) // not set
+                                                               precision = 6;
+                                                       o += dpsnprintf(o, end - o, va("%s %s %s", /* NESTED SPRINTF IS NESTED */ formatbuf, formatbuf, formatbuf),
+                                                               width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[0] : (double) GETARG_INTVECTOR(thisarg)[0]),
+                                                               width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[1] : (double) GETARG_INTVECTOR(thisarg)[1]),
+                                                               width, precision, (isfloat ? (double) GETARG_VECTOR(thisarg)[2] : (double) GETARG_INTVECTOR(thisarg)[2])
+                                                       );
+                                                       break;
                                                case 'c':
                                                        if(precision < 0) // not set
                                                                precision = end - o - 1;
@@ -6366,6 +6440,7 @@ void VM_getsurfacenumtriangles(void)
 //PF_getsurfacetriangle,     // #??? vector(entity e, float s, float n) getsurfacetriangle = #???;
 void VM_getsurfacetriangle(void)
 {
+       const vec3_t d = {-1, -1, -1};
        prvm_edict_t *ed;
        dp_model_t *model;
        msurface_t *surface;
@@ -6379,5 +6454,5 @@ void VM_getsurfacetriangle(void)
        if (trinum < 0 || trinum >= surface->num_triangles)
                return;
        // FIXME: implement rotation/scaling
-       VectorCopy(&(model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)[trinum * 3], PRVM_G_VECTOR(OFS_RETURN));
+       VectorMA(&(model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)[trinum * 3], surface->num_firstvertex, d, PRVM_G_VECTOR(OFS_RETURN));
 }