+void VM_gecko_resize( void ) {
+ const char *name;
+ float w, h;
+ clgecko_t *instance;
+
+ VM_SAFEPARMCOUNT( 3, VM_gecko_movemouse );
+
+ name = PRVM_G_STRING( OFS_PARM0 );
+ VM_CheckEmptyString( name );
+ w = PRVM_G_FLOAT( OFS_PARM1 );
+ h = PRVM_G_FLOAT( OFS_PARM2 );
+
+ instance = CL_Gecko_FindBrowser( name );
+ if( !instance ) {
+ return;
+ }
+ CL_Gecko_Resize( instance, (int) w, (int) h );
+}
+
+
+/*
+========================
+VM_gecko_get_texture_extent
+
+vector gecko_get_texture_extent( string name )
+========================
+*/
+void VM_gecko_get_texture_extent( void ) {
+ const char *name;
+ clgecko_t *instance;
+
+ VM_SAFEPARMCOUNT( 1, VM_gecko_movemouse );
+
+ name = PRVM_G_STRING( OFS_PARM0 );
+ VM_CheckEmptyString( name );
+
+ PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
+ instance = CL_Gecko_FindBrowser( name );
+ if( !instance ) {
+ PRVM_G_VECTOR(OFS_RETURN)[0] = 0;
+ PRVM_G_VECTOR(OFS_RETURN)[1] = 0;
+ return;
+ }
+ CL_Gecko_GetTextureExtent( instance,
+ PRVM_G_VECTOR(OFS_RETURN), PRVM_G_VECTOR(OFS_RETURN)+1 );
+}
+
+
+
+/*
+==============
+VM_makevectors
+
+Writes new values for v_forward, v_up, and v_right based on angles
+void makevectors(vector angle)
+==============
+*/
+void VM_makevectors (void)
+{
+ VM_SAFEPARMCOUNT(1, VM_makevectors);
+ AngleVectors(PRVM_G_VECTOR(OFS_PARM0), PRVM_gameglobalvector(v_forward), PRVM_gameglobalvector(v_right), PRVM_gameglobalvector(v_up));
+}
+
+/*
+==============
+VM_vectorvectors
+
+Writes new values for v_forward, v_up, and v_right based on the given forward vector
+vectorvectors(vector)
+==============
+*/
+void VM_vectorvectors (void)
+{
+ VM_SAFEPARMCOUNT(1, VM_vectorvectors);
+ VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), PRVM_gameglobalvector(v_forward));
+ VectorVectors(PRVM_gameglobalvector(v_forward), PRVM_gameglobalvector(v_right), PRVM_gameglobalvector(v_up));
+}
+
+/*
+========================
+VM_drawline
+
+void drawline(float width, vector pos1, vector pos2, vector rgb, float alpha, float flags)
+========================
+*/
+void VM_drawline (void)
+{
+ float *c1, *c2, *rgb;
+ float alpha, width;
+ unsigned char flags;
+
+ VM_SAFEPARMCOUNT(6, VM_drawline);
+ width = PRVM_G_FLOAT(OFS_PARM0);
+ c1 = PRVM_G_VECTOR(OFS_PARM1);
+ c2 = PRVM_G_VECTOR(OFS_PARM2);
+ rgb = PRVM_G_VECTOR(OFS_PARM3);
+ alpha = PRVM_G_FLOAT(OFS_PARM4);
+ flags = (int)PRVM_G_FLOAT(OFS_PARM5);
+ DrawQ_Line(width, c1[0], c1[1], c2[0], c2[1], rgb[0], rgb[1], rgb[2], alpha, flags);
+}
+
+// float(float number, float quantity) bitshift (EXT_BITSHIFT)
+void VM_bitshift (void)
+{
+ int n1, n2;
+ VM_SAFEPARMCOUNT(2, VM_bitshift);
+
+ n1 = (int)fabs((float)((int)PRVM_G_FLOAT(OFS_PARM0)));
+ n2 = (int)PRVM_G_FLOAT(OFS_PARM1);
+ if(!n1)
+ PRVM_G_FLOAT(OFS_RETURN) = n1;
+ else
+ if(n2 < 0)
+ PRVM_G_FLOAT(OFS_RETURN) = (n1 >> -n2);
+ else
+ PRVM_G_FLOAT(OFS_RETURN) = (n1 << n2);
+}
+
+////////////////////////////////////////
+// AltString functions
+////////////////////////////////////////
+
+/*
+========================
+VM_altstr_count
+
+float altstr_count(string)
+========================
+*/
+void VM_altstr_count( void )
+{
+ const char *altstr, *pos;
+ int count;
+
+ VM_SAFEPARMCOUNT( 1, VM_altstr_count );
+
+ altstr = PRVM_G_STRING( OFS_PARM0 );
+ //VM_CheckEmptyString( altstr );
+
+ for( count = 0, pos = altstr ; *pos ; pos++ ) {
+ if( *pos == '\\' ) {
+ if( !*++pos ) {
+ break;
+ }
+ } else if( *pos == '\'' ) {
+ count++;
+ }
+ }
+
+ PRVM_G_FLOAT( OFS_RETURN ) = (float) (count / 2);
+}
+
+/*
+========================
+VM_altstr_prepare
+
+string altstr_prepare(string)
+========================
+*/
+void VM_altstr_prepare( void )
+{
+ char *out;
+ const char *instr, *in;
+ int size;
+ char outstr[VM_STRINGTEMP_LENGTH];
+
+ VM_SAFEPARMCOUNT( 1, VM_altstr_prepare );
+
+ instr = PRVM_G_STRING( OFS_PARM0 );
+
+ for( out = outstr, in = instr, size = sizeof(outstr) - 1 ; size && *in ; size--, in++, out++ )
+ if( *in == '\'' ) {
+ *out++ = '\\';
+ *out = '\'';
+ size--;
+ } else
+ *out = *in;
+ *out = 0;
+
+ PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( outstr );
+}
+
+/*
+========================
+VM_altstr_get
+
+string altstr_get(string, float)
+========================
+*/
+void VM_altstr_get( void )
+{
+ const char *altstr, *pos;
+ char *out;
+ int count, size;
+ char outstr[VM_STRINGTEMP_LENGTH];
+
+ VM_SAFEPARMCOUNT( 2, VM_altstr_get );
+
+ altstr = PRVM_G_STRING( OFS_PARM0 );
+
+ count = (int)PRVM_G_FLOAT( OFS_PARM1 );
+ count = count * 2 + 1;
+
+ for( pos = altstr ; *pos && count ; pos++ )
+ if( *pos == '\\' ) {
+ if( !*++pos )
+ break;
+ } else if( *pos == '\'' )
+ count--;
+
+ if( !*pos ) {
+ PRVM_G_INT( OFS_RETURN ) = 0;
+ return;
+ }
+
+ for( out = outstr, size = sizeof(outstr) - 1 ; size && *pos ; size--, pos++, out++ )
+ if( *pos == '\\' ) {
+ if( !*++pos )
+ break;
+ *out = *pos;
+ size--;
+ } else if( *pos == '\'' )
+ break;
+ else
+ *out = *pos;
+
+ *out = 0;
+ PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( outstr );
+}
+
+/*
+========================
+VM_altstr_set
+
+string altstr_set(string altstr, float num, string set)
+========================
+*/
+void VM_altstr_set( void )
+{
+ int num;
+ const char *altstr, *str;
+ const char *in;
+ char *out;
+ char outstr[VM_STRINGTEMP_LENGTH];
+
+ VM_SAFEPARMCOUNT( 3, VM_altstr_set );
+
+ altstr = PRVM_G_STRING( OFS_PARM0 );
+
+ num = (int)PRVM_G_FLOAT( OFS_PARM1 );
+
+ str = PRVM_G_STRING( OFS_PARM2 );
+
+ out = outstr;
+ for( num = num * 2 + 1, in = altstr; *in && num; *out++ = *in++ )
+ if( *in == '\\' ) {
+ if( !*++in ) {
+ break;
+ }
+ } else if( *in == '\'' ) {
+ num--;
+ }
+
+ // copy set in
+ for( ; *str; *out++ = *str++ );
+ // now jump over the old content
+ for( ; *in ; in++ )
+ if( *in == '\'' || (*in == '\\' && !*++in) )
+ break;
+
+ strlcpy(out, in, outstr + sizeof(outstr) - out);
+ PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( outstr );
+}
+
+/*
+========================
+VM_altstr_ins
+insert after num
+string altstr_ins(string altstr, float num, string set)
+========================
+*/
+void VM_altstr_ins(void)
+{
+ int num;
+ const char *set;
+ const char *in;
+ char *out;
+ char outstr[VM_STRINGTEMP_LENGTH];
+
+ VM_SAFEPARMCOUNT(3, VM_altstr_ins);
+
+ in = PRVM_G_STRING( OFS_PARM0 );
+ num = (int)PRVM_G_FLOAT( OFS_PARM1 );
+ set = PRVM_G_STRING( OFS_PARM2 );
+
+ out = outstr;
+ for( num = num * 2 + 2 ; *in && num > 0 ; *out++ = *in++ )
+ if( *in == '\\' ) {
+ if( !*++in ) {
+ break;
+ }
+ } else if( *in == '\'' ) {
+ num--;
+ }
+
+ *out++ = '\'';
+ for( ; *set ; *out++ = *set++ );
+ *out++ = '\'';
+
+ strlcpy(out, in, outstr + sizeof(outstr) - out);
+ PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString( outstr );
+}
+
+
+////////////////////////////////////////
+// BufString functions
+////////////////////////////////////////
+//[515]: string buffers support
+
+static size_t stringbuffers_sortlength;
+
+static void BufStr_Expand(prvm_stringbuffer_t *stringbuffer, int strindex)
+{
+ if (stringbuffer->max_strings <= strindex)
+ {
+ char **oldstrings = stringbuffer->strings;
+ stringbuffer->max_strings = max(stringbuffer->max_strings * 2, 128);
+ while (stringbuffer->max_strings <= strindex)
+ stringbuffer->max_strings *= 2;
+ stringbuffer->strings = (char **) Mem_Alloc(prog->progs_mempool, stringbuffer->max_strings * sizeof(stringbuffer->strings[0]));
+ if (stringbuffer->num_strings > 0)
+ memcpy(stringbuffer->strings, oldstrings, stringbuffer->num_strings * sizeof(stringbuffer->strings[0]));
+ if (oldstrings)
+ Mem_Free(oldstrings);
+ }
+}
+
+static void BufStr_Shrink(prvm_stringbuffer_t *stringbuffer)
+{
+ // reduce num_strings if there are empty string slots at the end
+ while (stringbuffer->num_strings > 0 && stringbuffer->strings[stringbuffer->num_strings - 1] == NULL)
+ stringbuffer->num_strings--;
+
+ // if empty, free the string pointer array
+ if (stringbuffer->num_strings == 0)
+ {
+ stringbuffer->max_strings = 0;
+ if (stringbuffer->strings)
+ Mem_Free(stringbuffer->strings);
+ stringbuffer->strings = NULL;
+ }
+}
+
+static int BufStr_SortStringsUP (const void *in1, const void *in2)
+{
+ const char *a, *b;
+ a = *((const char **) in1);
+ b = *((const char **) in2);
+ if(!a || !a[0]) return 1;
+ if(!b || !b[0]) return -1;
+ return strncmp(a, b, stringbuffers_sortlength);
+}
+
+static int BufStr_SortStringsDOWN (const void *in1, const void *in2)
+{
+ const char *a, *b;
+ a = *((const char **) in1);
+ b = *((const char **) in2);
+ if(!a || !a[0]) return 1;
+ if(!b || !b[0]) return -1;
+ return strncmp(b, a, stringbuffers_sortlength);
+}
+
+/*
+========================
+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_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
+deletes buffer and all strings in it
+void buf_del(float bufhandle) = #461;
+========================
+*/
+void VM_buf_del (void)
+{
+ prvm_stringbuffer_t *stringbuffer;
+ 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);
+ }
+ else
+ {
+ VM_Warning("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)
+{
+ prvm_stringbuffer_t *stringbuffer;
+ VM_SAFEPARMCOUNT(1, VM_buf_getsize);
+
+ stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
+ if(!stringbuffer)
+ {
+ PRVM_G_FLOAT(OFS_RETURN) = -1;
+ VM_Warning("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) = stringbuffer->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)
+{
+ prvm_stringbuffer_t *srcstringbuffer, *dststringbuffer;
+ int i;
+ VM_SAFEPARMCOUNT(2, VM_buf_copy);
+
+ srcstringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
+ if(!srcstringbuffer)
+ {
+ VM_Warning("VM_buf_copy: invalid source buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+ i = (int)PRVM_G_FLOAT(OFS_PARM1);
+ if(i == (int)PRVM_G_FLOAT(OFS_PARM0))
+ {
+ VM_Warning("VM_buf_copy: source == destination (%i) in %s\n", i, PRVM_NAME);
+ return;
+ }
+ dststringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
+ if(!dststringbuffer)
+ {
+ VM_Warning("VM_buf_copy: invalid destination buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM1), PRVM_NAME);
+ return;
+ }
+
+ for (i = 0;i < dststringbuffer->num_strings;i++)
+ if (dststringbuffer->strings[i])
+ Mem_Free(dststringbuffer->strings[i]);
+ if (dststringbuffer->strings)
+ Mem_Free(dststringbuffer->strings);
+ *dststringbuffer = *srcstringbuffer;
+ if (dststringbuffer->max_strings)
+ dststringbuffer->strings = (char **)Mem_Alloc(prog->progs_mempool, sizeof(dststringbuffer->strings[0]) * dststringbuffer->max_strings);
+
+ for (i = 0;i < dststringbuffer->num_strings;i++)
+ {
+ if (srcstringbuffer->strings[i])
+ {
+ size_t stringlen;
+ stringlen = strlen(srcstringbuffer->strings[i]) + 1;
+ dststringbuffer->strings[i] = (char *)Mem_Alloc(prog->progs_mempool, stringlen);
+ memcpy(dststringbuffer->strings[i], srcstringbuffer->strings[i], stringlen);
+ }
+ }
+}
+
+/*
+========================
+VM_buf_sort
+sort buffer by beginnings of strings (cmplength defaults it's length)
+"backward == TRUE" means that sorting goes upside-down
+void buf_sort(float bufhandle, float cmplength, float backward) = #464;
+========================
+*/
+void VM_buf_sort (void)
+{
+ prvm_stringbuffer_t *stringbuffer;
+ VM_SAFEPARMCOUNT(3, VM_buf_sort);
+
+ stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
+ if(!stringbuffer)
+ {
+ VM_Warning("VM_buf_sort: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+ if(stringbuffer->num_strings <= 0)
+ {
+ VM_Warning("VM_buf_sort: tried to sort empty buffer %i in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+ stringbuffers_sortlength = (int)PRVM_G_FLOAT(OFS_PARM1);
+ if(stringbuffers_sortlength <= 0)
+ stringbuffers_sortlength = 0x7FFFFFFF;
+
+ if(!PRVM_G_FLOAT(OFS_PARM2))
+ qsort(stringbuffer->strings, stringbuffer->num_strings, sizeof(char*), BufStr_SortStringsUP);
+ else
+ qsort(stringbuffer->strings, stringbuffer->num_strings, sizeof(char*), BufStr_SortStringsDOWN);
+
+ BufStr_Shrink(stringbuffer);
+}
+
+/*
+========================
+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)
+{
+ prvm_stringbuffer_t *stringbuffer;
+ char k[VM_STRINGTEMP_LENGTH];
+ const char *sep;
+ int i;
+ size_t l;