+ Con_Printf("VM_buf_del: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+}
+
+/*
+========================
+VM_buf_getsize
+how many strings are stored in buffer
+float buf_getsize(float bufhandle) = #462;
+========================
+*/
+void VM_buf_getsize (void)
+{
+ qcstrbuffer_t *b;
+ VM_SAFEPARMCOUNT(1, VM_buf_getsize);
+
+ b = BUFSTR_BUFFER((int)PRVM_G_FLOAT(OFS_PARM0));
+ if(!b)
+ {
+ PRVM_G_FLOAT(OFS_RETURN) = -1;
+ Con_Printf("VM_buf_getsize: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+ else
+ PRVM_G_FLOAT(OFS_RETURN) = b->num_strings;
+}
+
+/*
+========================
+VM_buf_copy
+copy all content from one buffer to another, make sure it exists
+void buf_copy(float bufhandle_from, float bufhandle_to) = #463;
+========================
+*/
+void VM_buf_copy (void)
+{
+ qcstrbuffer_t *b1, *b2;
+ int i;
+ VM_SAFEPARMCOUNT(2, VM_buf_copy);
+
+ b1 = BUFSTR_BUFFER((int)PRVM_G_FLOAT(OFS_PARM0));
+ if(!b1)
+ {
+ Con_Printf("VM_buf_copy: invalid source buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+ i = PRVM_G_FLOAT(OFS_PARM1);
+ if(i == (int)PRVM_G_FLOAT(OFS_PARM0))
+ {
+ Con_Printf("VM_buf_copy: source == destination (%i) in %s\n", i, PRVM_NAME);
+ return;
+ }
+ b2 = BUFSTR_BUFFER(i);
+ if(!b2)
+ {
+ Con_Printf("VM_buf_copy: invalid destination buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM1), PRVM_NAME);
+ return;
+ }
+
+ BufStr_ClearBuffer(i);
+ qcstringbuffers[i] = malloc(sizeof(qcstrbuffer_t));
+ memset(qcstringbuffers[i], 0, sizeof(qcstrbuffer_t));
+ b2->num_strings = b1->num_strings;
+
+ for(i=0;i<b1->num_strings;i++)
+ if(b1->strings[i] && b1->strings[i][0])
+ {
+ b2->strings[i] = malloc(strlen(b1->strings[i])+1);
+ if(!b2->strings[i])
+ {
+ Con_Printf("VM_buf_copy: not enough memory for buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM1), PRVM_NAME);
+ break;
+ }
+ strcpy(b2->strings[i], b1->strings[i]);
+ }
+}
+
+/*
+========================
+VM_buf_sort
+sort buffer by beginnings of strings (sortpower defaults it's lenght)
+"backward == TRUE" means that sorting goes upside-down
+void buf_sort(float bufhandle, float sortpower, float backward) = #464;
+========================
+*/
+void VM_buf_sort (void)
+{
+ qcstrbuffer_t *b;
+ int i;
+ VM_SAFEPARMCOUNT(3, VM_buf_sort);
+
+ b = BUFSTR_BUFFER((int)PRVM_G_FLOAT(OFS_PARM0));
+ if(!b)
+ {
+ Con_Printf("VM_buf_sort: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+ if(b->num_strings <= 0)
+ {
+ Con_Printf("VM_buf_sort: tried to sort empty buffer %i in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+ buf_sortpower = PRVM_G_FLOAT(OFS_PARM1);
+ if(buf_sortpower <= 0)
+ buf_sortpower = 99999999;
+
+ if(!PRVM_G_FLOAT(OFS_PARM2))
+ qsort(b->strings, b->num_strings, sizeof(char*), BufStr_SortStringsUP);
+ else
+ qsort(b->strings, b->num_strings, sizeof(char*), BufStr_SortStringsDOWN);
+
+ for(i=b->num_strings-1;i>=0;i--) //[515]: delete empty lines
+ if(b->strings)
+ {
+ if(b->strings[i][0])
+ break;
+ else
+ {
+ free(b->strings[i]);
+ --b->num_strings;
+ b->strings[i] = NULL;
+ }
+ }
+ else
+ --b->num_strings;
+}
+
+/*
+========================
+VM_buf_implode
+concantenates all buffer string into one with "glue" separator and returns it as tempstring
+string buf_implode(float bufhandle, string glue) = #465;
+========================
+*/
+void VM_buf_implode (void)
+{
+ qcstrbuffer_t *b;
+ char *k;
+ const char *sep;
+ int i;
+ size_t l;
+ VM_SAFEPARMCOUNT(2, VM_buf_implode);
+
+ b = BUFSTR_BUFFER((int)PRVM_G_FLOAT(OFS_PARM0));
+ PRVM_G_INT(OFS_RETURN) = 0;
+ if(!b)
+ {
+ Con_Printf("VM_buf_implode: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+ if(!b->num_strings)
+ return;
+ sep = PRVM_G_STRING(OFS_PARM1);
+ k = VM_GetTempString();
+ k[0] = 0;
+ for(l=i=0;i<b->num_strings;i++)
+ if(b->strings[i])
+ {
+ l += strlen(b->strings[i]);
+ if(l>=4095)
+ break;
+ k = strcat(k, b->strings[i]);
+ if(!k)
+ break;
+ if(sep && (i != b->num_strings-1))
+ {
+ l += strlen(sep);
+ if(l>=4095)
+ break;
+ k = strcat(k, sep);
+ if(!k)
+ break;
+ }
+ }
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(k);
+}
+
+/*
+========================
+VM_bufstr_get
+get a string from buffer, returns direct pointer, dont str_unzone it!
+string bufstr_get(float bufhandle, float string_index) = #465;
+========================
+*/
+void VM_bufstr_get (void)
+{
+ qcstrbuffer_t *b;
+ int strindex;
+ VM_SAFEPARMCOUNT(2, VM_bufstr_get);
+
+ b = BUFSTR_BUFFER((int)PRVM_G_FLOAT(OFS_PARM0));
+ if(!b)
+ {
+ Con_Printf("VM_bufstr_get: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+ strindex = (int)PRVM_G_FLOAT(OFS_PARM1);
+ if(strindex < 0 || strindex > MAX_QCSTR_STRINGS)
+ {
+ Con_Printf("VM_bufstr_get: invalid string index %i used in %s\n", strindex, PRVM_NAME);
+ return;
+ }
+ PRVM_G_INT(OFS_RETURN) = 0;
+ if(b->num_strings <= strindex)
+ return;
+ if(b->strings[strindex])
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(b->strings[strindex]);
+}
+
+/*
+========================
+VM_bufstr_set
+copies a string into selected slot of buffer
+void bufstr_set(float bufhandle, float string_index, string str) = #466;
+========================
+*/
+void VM_bufstr_set (void)
+{
+ int bufindex, strindex;
+ qcstrbuffer_t *b;
+ const char *news;
+
+ VM_SAFEPARMCOUNT(3, VM_bufstr_set);
+
+ bufindex = PRVM_G_FLOAT(OFS_PARM0);
+ b = BUFSTR_BUFFER(bufindex);
+ if(!b)
+ {
+ Con_Printf("VM_bufstr_set: invalid buffer %i used in %s\n", bufindex, PRVM_NAME);
+ return;
+ }
+ strindex = PRVM_G_FLOAT(OFS_PARM1);
+ if(strindex < 0 || strindex > MAX_QCSTR_STRINGS)
+ {
+ Con_Printf("VM_bufstr_set: invalid string index %i used in %s\n", strindex, PRVM_NAME);
+ return;
+ }
+ news = PRVM_G_STRING(OFS_PARM2);
+ if(!news)
+ {
+ Con_Printf("VM_bufstr_set: null string used in %s\n", PRVM_NAME);
+ return;
+ }
+ if(b->strings[strindex])
+ free(b->strings[strindex]);
+ b->strings[strindex] = malloc(strlen(news)+1);
+ strcpy(b->strings[strindex], news);
+}
+
+/*
+========================
+VM_bufstr_add
+adds string to buffer in nearest free slot and returns it
+"order == TRUE" means that string will be added after last "full" slot
+float bufstr_add(float bufhandle, string str, float order) = #467;
+========================
+*/
+void VM_bufstr_add (void)
+{
+ int bufindex, order, strindex;
+ qcstrbuffer_t *b;
+ const char *string;
+
+ VM_SAFEPARMCOUNT(3, VM_bufstr_add);
+
+ bufindex = PRVM_G_FLOAT(OFS_PARM0);
+ b = BUFSTR_BUFFER(bufindex);
+ PRVM_G_FLOAT(OFS_RETURN) = -1;
+ if(!b)
+ {
+ Con_Printf("VM_bufstr_add: invalid buffer %i used in %s\n", bufindex, PRVM_NAME);
+ return;
+ }
+ string = PRVM_G_STRING(OFS_PARM1);
+ if(!string)
+ {
+ Con_Printf("VM_bufstr_add: null string used in %s\n", PRVM_NAME);
+ return;
+ }
+
+ order = PRVM_G_FLOAT(OFS_PARM2);
+ if(order)
+ strindex = b->num_strings;
+ else
+ {
+ strindex = BufStr_FindFreeString(b);
+ if(strindex < 0)
+ {
+ Con_Printf("VM_bufstr_add: buffer %i has no free string slots in %s\n", bufindex, PRVM_NAME);
+ return;
+ }
+ }
+
+ while(b->num_strings <= strindex)
+ {
+ if(b->num_strings == MAX_QCSTR_STRINGS)
+ {
+ Con_Printf("VM_bufstr_add: buffer %i has no free string slots in %s\n", bufindex, PRVM_NAME);
+ return;
+ }
+ b->strings[b->num_strings] = NULL;
+ b->num_strings++;
+ }
+ if(b->strings[strindex])
+ free(b->strings[strindex]);
+ b->strings[strindex] = malloc(strlen(string)+1);
+ strcpy(b->strings[strindex], string);
+ PRVM_G_FLOAT(OFS_RETURN) = strindex;
+}
+
+/*
+========================
+VM_bufstr_free
+delete string from buffer
+void bufstr_free(float bufhandle, float string_index) = #468;
+========================
+*/
+void VM_bufstr_free (void)
+{
+ int i;
+ qcstrbuffer_t *b;
+ VM_SAFEPARMCOUNT(2, VM_bufstr_free);
+
+ b = BUFSTR_BUFFER((int)PRVM_G_FLOAT(OFS_PARM0));
+ if(!b)
+ {
+ Con_Printf("VM_bufstr_free: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+ i = PRVM_G_FLOAT(OFS_PARM1);
+ if(i < 0 || i > MAX_QCSTR_STRINGS)
+ {
+ Con_Printf("VM_bufstr_free: invalid string index %i used in %s\n", i, PRVM_NAME);
+ return;
+ }
+ if(b->strings[i])
+ free(b->strings[i]);
+ b->strings[i] = NULL;
+ if(i+1 == b->num_strings)
+ --b->num_strings;
+}
+
+//=============
+
+void VM_Cmd_Init(void)
+{
+ // only init the stuff for the current prog
+ 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)
+{
+ CL_PurgeOwner( MENUOWNER );
+ VM_Search_Reset();
+ VM_Files_CloseAll();
+// VM_BufStr_ShutDown();
+ if(vm_polygons_initialized)
+ {
+ Mem_FreePool(&vm_polygons_pool);
+ vm_polygons_initialized = false;
+ }