added BX_WAL_SUPPORT to extensions list and documented it (.wal texture support has...
[xonotic/darkplaces.git] / mvm_cmds.c
1 #include "prvm_cmds.h"
2
3 //============================================================================
4 // Menu
5
6 char *vm_m_extensions =
7 "BX_WAL_SUPPORT "
8 "DP_CINEMATIC_DPV "
9 "DP_MENU_EXTRESPONSEPACKET "
10 "DP_QC_ASINACOSATANATAN2TAN "
11 "DP_QC_STRINGCOLORFUNCTIONS "
12 "DP_QC_UNLIMITEDTEMPSTRINGS";
13
14 /*
15 =========
16 VM_M_precache_file
17
18 string  precache_file(string)
19 =========
20 */
21 void VM_M_precache_file (void)
22 {       // precache_file is only used to copy files with qcc, it does nothing
23         VM_SAFEPARMCOUNT(1,VM_precache_file);
24
25         PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
26 }
27
28 /*
29 =========
30 VM_M_preache_error
31
32 used instead of the other VM_precache_* functions in the builtin list
33 =========
34 */
35
36 void VM_M_precache_error (void)
37 {
38         PRVM_ERROR ("PF_Precache_*: Precache can only be done in spawn functions");
39 }
40
41 /*
42 =========
43 VM_M_precache_sound
44
45 string  precache_sound (string sample)
46 =========
47 */
48 void VM_M_precache_sound (void)
49 {
50         const char      *s;
51
52         VM_SAFEPARMCOUNT(1, VM_precache_sound);
53
54         s = PRVM_G_STRING(OFS_PARM0);
55         PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
56         VM_CheckEmptyString (s);
57
58         if(snd_initialized.integer && !S_PrecacheSound (s,true, true))
59         {
60                 VM_Warning("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
61                 return;
62         }
63 }
64
65 /*
66 =========
67 VM_M_setmousetarget
68
69 setmousetarget(float target)
70 =========
71 */
72 void VM_M_setmousetarget(void)
73 {
74         VM_SAFEPARMCOUNT(1, VM_M_setmousetarget);
75
76         switch((int)PRVM_G_FLOAT(OFS_PARM0))
77         {
78         case 1:
79                 in_client_mouse = false;
80                 break;
81         case 2:
82                 in_client_mouse = true;
83                 break;
84         default:
85                 PRVM_ERROR("VM_M_setmousetarget: wrong destination %f !",PRVM_G_FLOAT(OFS_PARM0));
86         }
87 }
88
89 /*
90 =========
91 VM_M_getmousetarget
92
93 float   getmousetarget
94 =========
95 */
96 void VM_M_getmousetarget(void)
97 {
98         VM_SAFEPARMCOUNT(0,VM_M_getmousetarget);
99
100         if(in_client_mouse)
101                 PRVM_G_FLOAT(OFS_RETURN) = 2;
102         else
103                 PRVM_G_FLOAT(OFS_RETURN) = 1;
104 }
105
106
107
108 /*
109 =========
110 VM_M_setkeydest
111
112 setkeydest(float dest)
113 =========
114 */
115 void VM_M_setkeydest(void)
116 {
117         VM_SAFEPARMCOUNT(1,VM_M_setkeydest);
118
119         switch((int)PRVM_G_FLOAT(OFS_PARM0))
120         {
121         case 0:
122                 // key_game
123                 key_dest = key_game;
124                 break;
125         case 2:
126                 // key_menu
127                 key_dest = key_menu;
128                 break;
129         case 1:
130                 // key_message
131                 // key_dest = key_message
132                 // break;
133         default:
134                 PRVM_ERROR("VM_M_setkeydest: wrong destination %f !", PRVM_G_FLOAT(OFS_PARM0));
135         }
136 }
137
138 /*
139 =========
140 VM_M_getkeydest
141
142 float   getkeydest
143 =========
144 */
145 void VM_M_getkeydest(void)
146 {
147         VM_SAFEPARMCOUNT(0,VM_M_getkeydest);
148
149         // key_game = 0, key_message = 1, key_menu = 2, unknown = 3
150         switch(key_dest)
151         {
152         case key_game:
153                 PRVM_G_FLOAT(OFS_RETURN) = 0;
154                 break;
155         case key_menu:
156                 PRVM_G_FLOAT(OFS_RETURN) = 2;
157                 break;
158         case key_message:
159                 // not supported
160                 // PRVM_G_FLOAT(OFS_RETURN) = 1;
161                 // break;
162         default:
163                 PRVM_G_FLOAT(OFS_RETURN) = 3;
164         }
165 }
166
167 /*
168 =========
169 VM_M_callfunction
170
171         callfunction(...,string function_name)
172 Extension: pass
173 =========
174 */
175 mfunction_t *PRVM_ED_FindFunction (const char *name);
176 void VM_M_callfunction(void)
177 {
178         mfunction_t *func;
179         const char *s;
180
181         if(prog->argc == 0)
182                 PRVM_ERROR("VM_M_callfunction: 1 parameter is required !");
183
184         s = PRVM_G_STRING(OFS_PARM0 + (prog->argc - 1));
185
186         VM_CheckEmptyString(s);
187
188         func = PRVM_ED_FindFunction(s);
189
190         if(!func)
191                 PRVM_ERROR("VM_M_callfunciton: function %s not found !", s);
192         else if (func->first_statement < 0)
193         {
194                 // negative statements are built in functions
195                 int builtinnumber = -func->first_statement;
196                 prog->xfunction->builtinsprofile++;
197                 if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
198                         prog->builtins[builtinnumber]();
199                 else
200                         PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME);
201         }
202         else if(func > 0)
203         {
204                 prog->argc--;
205                 PRVM_ExecuteProgram(func - prog->functions,"");
206                 prog->argc++;
207         }
208 }
209
210 /*
211 =========
212 VM_M_isfunction
213
214 float   isfunction(string function_name)
215 =========
216 */
217 mfunction_t *PRVM_ED_FindFunction (const char *name);
218 void VM_M_isfunction(void)
219 {
220         mfunction_t *func;
221         const char *s;
222
223         VM_SAFEPARMCOUNT(1, VM_M_isfunction);
224
225         s = PRVM_G_STRING(OFS_PARM0);
226
227         VM_CheckEmptyString(s);
228
229         func = PRVM_ED_FindFunction(s);
230
231         if(!func)
232                 PRVM_G_FLOAT(OFS_RETURN) = false;
233         else
234                 PRVM_G_FLOAT(OFS_RETURN) = true;
235 }
236
237 /*
238 =========
239 VM_M_writetofile
240
241         writetofile(float fhandle, entity ent)
242 =========
243 */
244 void VM_M_writetofile(void)
245 {
246         prvm_edict_t * ent;
247         qfile_t *file;
248
249         VM_SAFEPARMCOUNT(2, VM_M_writetofile);
250
251         file = VM_GetFileHandle( (int)PRVM_G_FLOAT(OFS_PARM0) );
252         if( !file )
253         {
254                 VM_Warning("VM_M_writetofile: invalid or closed file handle\n");
255                 return;
256         }
257
258         ent = PRVM_G_EDICT(OFS_PARM1);
259         if(ent->priv.required->free)
260         {
261                 VM_Warning("VM_M_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent));
262                 return;
263         }
264
265         PRVM_ED_Write (file, ent);
266 }
267
268 /*
269 =========
270 VM_M_getresolution
271
272 vector  getresolution(float number)
273 =========
274 */
275 extern unsigned short video_resolutions[][2];
276 void VM_M_getresolution(void)
277 {
278         int nr;
279         VM_SAFEPARMCOUNT(1, VM_getresolution);
280
281         nr = (int)PRVM_G_FLOAT(OFS_PARM0);
282
283
284         PRVM_G_VECTOR(OFS_RETURN)[0] = video_resolutions[nr][0];
285         PRVM_G_VECTOR(OFS_RETURN)[1] = video_resolutions[nr][1];
286         PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
287 }
288
289 /*
290 =========
291 VM_M_findkeysforcommand
292
293 string  findkeysforcommand(string command)
294
295 the returned string is an altstring
296 =========
297 */
298 #define NUMKEYS 5 // TODO: merge the constant in keys.c with this one somewhen
299
300 void M_FindKeysForCommand(const char *command, int *keys);
301 void VM_M_findkeysforcommand(void)
302 {
303         const char *cmd;
304         char ret[VM_STRINGTEMP_LENGTH];
305         int keys[NUMKEYS];
306         int i;
307
308         VM_SAFEPARMCOUNT(1, VM_M_findkeysforcommand);
309
310         cmd = PRVM_G_STRING(OFS_PARM0);
311
312         VM_CheckEmptyString(cmd);
313
314         M_FindKeysForCommand(cmd, keys);
315
316         ret[0] = 0;
317         for(i = 0; i < NUMKEYS; i++)
318                 strlcat(ret, va(" \'%i\'", keys[i]), sizeof(ret));
319
320         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(ret);
321 }
322
323 /*
324 =========
325 VM_M_getserverliststat
326
327 float   getserverliststat(float type)
328 =========
329 */
330 /*
331         type:
332 0       serverlist_viewcount
333 1   serverlist_totalcount
334 2       masterquerycount
335 3       masterreplycount
336 4       serverquerycount
337 5       serverreplycount
338 6       sortfield
339 7       sortdescending
340 */
341 void VM_M_getserverliststat( void )
342 {
343         int type;
344         VM_SAFEPARMCOUNT ( 1, VM_M_getserverliststat );
345
346         PRVM_G_FLOAT( OFS_RETURN ) = 0;
347
348         type = (int)PRVM_G_FLOAT( OFS_PARM0 );
349         switch(type)
350         {
351         case 0:
352                 PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_viewcount;
353                 return;
354         case 1:
355                 PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_cachecount;
356         case 2:
357                 PRVM_G_FLOAT ( OFS_RETURN ) = masterquerycount;
358                 return;
359         case 3:
360                 PRVM_G_FLOAT ( OFS_RETURN ) = masterreplycount;
361                 return;
362         case 4:
363                 PRVM_G_FLOAT ( OFS_RETURN ) = serverquerycount;
364                 return;
365         case 5:
366                 PRVM_G_FLOAT ( OFS_RETURN ) = serverreplycount;
367                 return;
368         case 6:
369                 PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_sortbyfield;
370                 return;
371         case 7:
372                 PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_sortdescending;
373                 return;
374         default:
375                 VM_Warning( "VM_M_getserverliststat: bad type %i!\n", type );
376         }
377 }
378
379 /*
380 ========================
381 VM_M_resetserverlistmasks
382
383 resetserverlistmasks()
384 ========================
385 */
386 void VM_M_resetserverlistmasks( void )
387 {
388         ServerList_ResetMasks();
389 }
390
391
392 /*
393 ========================
394 VM_M_setserverlistmaskstring
395
396 setserverlistmaskstring(float mask, float fld, string str, float op)
397 0-511           and
398 512 - 1024      or
399 ========================
400 */
401 void VM_M_setserverlistmaskstring( void )
402 {
403         const char *str;
404         int masknr;
405         serverlist_mask_t *mask;
406         int field;
407
408         VM_SAFEPARMCOUNT( 4, VM_M_setserverlistmaskstring );
409         str = PRVM_G_STRING( OFS_PARM2 );
410
411         masknr = (int)PRVM_G_FLOAT( OFS_PARM0 );
412         if( masknr >= 0 && masknr <= SERVERLIST_ANDMASKCOUNT )
413                 mask = &serverlist_andmasks[masknr];
414         else if( masknr >= 512 && masknr - 512 <= SERVERLIST_ORMASKCOUNT )
415                 mask = &serverlist_ormasks[masknr - 512 ];
416         else
417         {
418                 VM_Warning( "VM_M_setserverlistmaskstring: invalid mask number %i\n", masknr );
419                 return;
420         }
421
422         field = (int) PRVM_G_FLOAT( OFS_PARM1 );
423
424         switch( field ) {
425                 case SLIF_CNAME:
426                         strlcpy( mask->info.cname, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.cname) );
427                         break;
428                 case SLIF_NAME:
429                         strlcpy( mask->info.name, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.name)  );
430                         break;
431                 case SLIF_MAP:
432                         strlcpy( mask->info.map, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.map)  );
433                         break;
434                 case SLIF_MOD:
435                         strlcpy( mask->info.mod, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.mod)  );
436                         break;
437                 case SLIF_GAME:
438                         strlcpy( mask->info.game, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.game)  );
439                         break;
440                 default:
441                         VM_Warning( "VM_M_setserverlistmaskstring: Bad field number %i passed!\n", field );
442                         return;
443         }
444
445         mask->active = true;
446         mask->tests[field] = (serverlist_maskop_t)((int)PRVM_G_FLOAT( OFS_PARM3 ));
447 }
448
449 /*
450 ========================
451 VM_M_setserverlistmasknumber
452
453 setserverlistmasknumber(float mask, float fld, float num, float op)
454
455 0-511           and
456 512 - 1024      or
457 ========================
458 */
459 void VM_M_setserverlistmasknumber( void )
460 {
461         int number;
462         serverlist_mask_t *mask;
463         int     masknr;
464         int field;
465         VM_SAFEPARMCOUNT( 4, VM_M_setserverlistmasknumber );
466
467         masknr = (int)PRVM_G_FLOAT( OFS_PARM0 );
468         if( masknr >= 0 && masknr <= SERVERLIST_ANDMASKCOUNT )
469                 mask = &serverlist_andmasks[masknr];
470         else if( masknr >= 512 && masknr - 512 <= SERVERLIST_ORMASKCOUNT )
471                 mask = &serverlist_ormasks[masknr - 512 ];
472         else
473         {
474                 VM_Warning( "VM_M_setserverlistmasknumber: invalid mask number %i\n", masknr );
475                 return;
476         }
477
478         number = (int)PRVM_G_FLOAT( OFS_PARM2 );
479         field = (int) PRVM_G_FLOAT( OFS_PARM1 );
480
481         switch( field ) {
482                 case SLIF_MAXPLAYERS:
483                         mask->info.maxplayers = number;
484                         break;
485                 case SLIF_NUMPLAYERS:
486                         mask->info.numplayers = number;
487                         break;
488                 case SLIF_PING:
489                         mask->info.ping = number;
490                         break;
491                 case SLIF_PROTOCOL:
492                         mask->info.protocol = number;
493                         break;
494                 default:
495                         VM_Warning( "VM_M_setserverlistmasknumber: Bad field number %i passed!\n", field );
496                         return;
497         }
498
499         mask->active = true;
500         mask->tests[field] = (serverlist_maskop_t)((int)PRVM_G_FLOAT( OFS_PARM3 ));
501 }
502
503
504 /*
505 ========================
506 VM_M_resortserverlist
507
508 resortserverlist
509 ========================
510 */
511 void VM_M_resortserverlist( void )
512 {
513         ServerList_RebuildViewList();
514 }
515
516 /*
517 =========
518 VM_M_getserverliststring
519
520 string  getserverliststring(float field, float hostnr)
521 =========
522 */
523 void VM_M_getserverliststring(void)
524 {
525         serverlist_entry_t *cache;
526         int hostnr;
527
528         VM_SAFEPARMCOUNT(2, VM_M_getserverliststring);
529
530         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
531
532         hostnr = (int)PRVM_G_FLOAT(OFS_PARM1);
533
534         if(hostnr < 0 || hostnr >= serverlist_viewcount)
535         {
536                 Con_Print("VM_M_getserverliststring: bad hostnr passed!\n");
537                 return;
538         }
539         cache = serverlist_viewlist[hostnr];
540         switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) {
541                 case SLIF_CNAME:
542                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.cname );
543                         break;
544                 case SLIF_NAME:
545                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.name );
546                         break;
547                 case SLIF_GAME:
548                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.game );
549                         break;
550                 case SLIF_MOD:
551                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.mod );
552                         break;
553                 case SLIF_MAP:
554                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.map );
555                         break;
556                 // TODO remove this again
557                 case 1024:
558                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->line1 );
559                         break;
560                 case 1025:
561                         PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->line2 );
562                         break;
563                 default:
564                         Con_Print("VM_M_getserverliststring: bad field number passed!\n");
565         }
566 }
567
568 /*
569 =========
570 VM_M_getserverlistnumber
571
572 float   getserverlistnumber(float field, float hostnr)
573 =========
574 */
575 void VM_M_getserverlistnumber(void)
576 {
577         serverlist_entry_t *cache;
578         int hostnr;
579
580         VM_SAFEPARMCOUNT(2, VM_M_getserverliststring);
581
582         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
583
584         hostnr = (int)PRVM_G_FLOAT(OFS_PARM1);
585
586         if(hostnr < 0 || hostnr >= serverlist_viewcount)
587         {
588                 Con_Print("VM_M_getserverliststring: bad hostnr passed!\n");
589                 return;
590         }
591         cache = serverlist_viewlist[hostnr];
592         switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) {
593                 case SLIF_MAXPLAYERS:
594                         PRVM_G_FLOAT( OFS_RETURN ) = cache->info.maxplayers;
595                         break;
596                 case SLIF_NUMPLAYERS:
597                         PRVM_G_FLOAT( OFS_RETURN ) = cache->info.numplayers;
598                         break;
599                 case SLIF_PING:
600                         PRVM_G_FLOAT( OFS_RETURN ) = cache->info.ping;
601                         break;
602                 case SLIF_PROTOCOL:
603                         PRVM_G_FLOAT( OFS_RETURN ) = cache->info.protocol;
604                         break;
605                 default:
606                         Con_Print("VM_M_getserverlistnumber: bad field number passed!\n");
607         }
608 }
609
610 /*
611 ========================
612 VM_M_setserverlistsort
613
614 setserverlistsort(float field, float descending)
615 ========================
616 */
617 void VM_M_setserverlistsort( void )
618 {
619         VM_SAFEPARMCOUNT( 2, VM_M_setserverlistsort );
620
621         serverlist_sortbyfield = (serverlist_infofield_t)((int)PRVM_G_FLOAT( OFS_PARM0 ));
622         serverlist_sortdescending = (qboolean) PRVM_G_FLOAT( OFS_PARM1 );
623 }
624
625 /*
626 ========================
627 VM_M_refreshserverlist
628
629 refreshserverlist()
630 ========================
631 */
632 void VM_M_refreshserverlist( void )
633 {
634         VM_SAFEPARMCOUNT( 0, VM_M_refreshserverlist );
635         ServerList_QueryList(true, false);
636 }
637
638 /*
639 ========================
640 VM_M_getserverlistindexforkey
641
642 float getserverlistindexforkey(string key)
643 ========================
644 */
645 void VM_M_getserverlistindexforkey( void )
646 {
647         const char *key;
648         VM_SAFEPARMCOUNT( 1, VM_M_getserverlistindexforkey );
649
650         key = PRVM_G_STRING( OFS_PARM0 );
651         VM_CheckEmptyString( key );
652
653         if( !strcmp( key, "cname" ) )
654                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_CNAME;
655         else if( !strcmp( key, "ping" ) )
656                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_PING;
657         else if( !strcmp( key, "game" ) )
658                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_GAME;
659         else if( !strcmp( key, "mod" ) )
660                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_MOD;
661         else if( !strcmp( key, "map" ) )
662                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_MAP;
663         else if( !strcmp( key, "name" ) )
664                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_NAME;
665         else if( !strcmp( key, "maxplayers" ) )
666                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_MAXPLAYERS;
667         else if( !strcmp( key, "numplayers" ) )
668                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_NUMPLAYERS;
669         else if( !strcmp( key, "protocol" ) )
670                 PRVM_G_FLOAT( OFS_RETURN ) = SLIF_PROTOCOL;
671         else
672                 PRVM_G_FLOAT( OFS_RETURN ) = -1;
673 }
674
675 /*
676 ========================
677 VM_M_addwantedserverlistkey
678
679 addwantedserverlistkey(string key)
680 ========================
681 */
682 void VM_M_addwantedserverlistkey( void )
683 {
684         VM_SAFEPARMCOUNT( 1, VM_M_addwantedserverlistkey );
685 }
686
687 /*
688 ===============================================================================
689 MESSAGE WRITING
690
691 used only for client and menu
692 severs uses VM_SV_...
693
694 Write*(* data, float type, float to)
695
696 ===============================================================================
697 */
698
699 #define MSG_BROADCAST   0               // unreliable to all
700 #define MSG_ONE                 1               // reliable to one (msg_entity)
701 #define MSG_ALL                 2               // reliable to all
702 #define MSG_INIT                3               // write to the init string
703
704 sizebuf_t *VM_WriteDest (void)
705 {
706         int             dest;
707         int             destclient;
708
709         if(!sv.active)
710                 PRVM_ERROR("VM_WriteDest: game is not server (%s)", PRVM_NAME);
711
712         dest = (int)PRVM_G_FLOAT(OFS_PARM1);
713         switch (dest)
714         {
715         case MSG_BROADCAST:
716                 return &sv.datagram;
717
718         case MSG_ONE:
719                 destclient = (int) PRVM_G_FLOAT(OFS_PARM2);
720                 if (destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active || !svs.clients[destclient].netconnection)
721                         PRVM_ERROR("VM_clientcommand: %s: invalid client !", PRVM_NAME);
722
723                 return &svs.clients[destclient].netconnection->message;
724
725         case MSG_ALL:
726                 return &sv.reliable_datagram;
727
728         case MSG_INIT:
729                 return &sv.signon;
730
731         default:
732                 PRVM_ERROR ("WriteDest: bad destination");
733                 break;
734         }
735
736         return NULL;
737 }
738
739 void VM_M_WriteByte (void)
740 {
741         MSG_WriteByte (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
742 }
743
744 void VM_M_WriteChar (void)
745 {
746         MSG_WriteChar (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
747 }
748
749 void VM_M_WriteShort (void)
750 {
751         MSG_WriteShort (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
752 }
753
754 void VM_M_WriteLong (void)
755 {
756         MSG_WriteLong (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
757 }
758
759 void VM_M_WriteAngle (void)
760 {
761         MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
762 }
763
764 void VM_M_WriteCoord (void)
765 {
766         MSG_WriteCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
767 }
768
769 void VM_M_WriteString (void)
770 {
771         MSG_WriteString (VM_WriteDest(), PRVM_G_STRING(OFS_PARM0));
772 }
773
774 void VM_M_WriteEntity (void)
775 {
776         MSG_WriteShort (VM_WriteDest(), PRVM_G_EDICTNUM(OFS_PARM0));
777 }
778
779 //string(void) getextresponse = #624; // returns the next extResponse packet that was sent to this client
780 void VM_M_getextresponse (void)
781 {
782         VM_SAFEPARMCOUNT(0,VM_argv);
783
784         if (net_extresponse_count <= 0)
785                 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
786         else
787         {
788                 int first;
789                 --net_extresponse_count;
790                 first = (net_extresponse_last + NET_EXTRESPONSE_MAX - net_extresponse_count) % NET_EXTRESPONSE_MAX;
791                 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(net_extresponse[first]);
792         }
793 }
794
795 prvm_builtin_t vm_m_builtins[] = {
796         0, // to be consistent with the old vm
797         // common builtings (mostly)
798         VM_checkextension,
799         VM_error,
800         VM_objerror,
801         VM_print,
802         VM_bprint,
803         VM_sprint,
804         VM_centerprint,
805         VM_normalize,
806         VM_vlen,
807         VM_vectoyaw,    // #10
808         VM_vectoangles,
809         VM_random,
810         VM_localcmd,
811         VM_cvar,
812         VM_cvar_set,
813         VM_dprint,
814         VM_ftos,
815         VM_fabs,
816         VM_vtos,
817         VM_etos,                // 20
818         VM_stof,
819         VM_spawn,
820         VM_remove,
821         VM_find,
822         VM_findfloat,
823         VM_findchain,
824         VM_findchainfloat,
825         VM_M_precache_file,
826         VM_M_precache_sound,
827         VM_coredump,    // 30
828         VM_traceon,
829         VM_traceoff,
830         VM_eprint,
831         VM_rint,
832         VM_floor,
833         VM_ceil,
834         VM_nextent,
835         VM_sin,
836         VM_cos,
837         VM_sqrt,                // 40
838         VM_randomvec,
839         VM_registercvar,
840         VM_min,
841         VM_max,
842         VM_bound,
843         VM_pow,
844         VM_copyentity,
845         VM_fopen,
846         VM_fclose,
847         VM_fgets,               // 50
848         VM_fputs,
849         VM_strlen,
850         VM_strcat,
851         VM_substring,
852         VM_stov,
853         VM_strzone,
854         VM_strunzone,
855         VM_tokenize,
856         VM_argv,
857         VM_isserver,    // 60
858         VM_clientcount,
859         VM_clientstate,
860         VM_clcommand,
861         VM_changelevel,
862         VM_localsound,
863         VM_getmousepos,
864         VM_gettime,
865         VM_loadfromdata,
866         VM_loadfromfile,
867         VM_modulo,              // 70
868         VM_cvar_string,
869         VM_crash,
870         VM_stackdump,   // 73
871         VM_search_begin,
872         VM_search_end,
873         VM_search_getsize,
874         VM_search_getfilename, // 77
875         VM_chr,
876         VM_itof,
877         VM_ftoe,                // 80
878         VM_itof,                // isString
879         VM_altstr_count,
880         VM_altstr_prepare,
881         VM_altstr_get,
882         VM_altstr_set,
883         VM_altstr_ins,
884         VM_findflags,
885         VM_findchainflags,
886         VM_cvar_defstring, // 89
887         0, // 90
888         e10,                    // 100
889         e100,                   // 200
890         e100,                   // 300
891         e100,                   // 400
892         // msg functions
893         VM_M_WriteByte,
894         VM_M_WriteChar,
895         VM_M_WriteShort,
896         VM_M_WriteLong,
897         VM_M_WriteAngle,
898         VM_M_WriteCoord,
899         VM_M_WriteString,
900         VM_M_WriteEntity,       // 408
901         0,
902         0,                              // 410
903         e10,                    // 420
904         e10,                    // 430
905         e10,                    // 440
906         e10,                    // 450
907         // draw functions
908         VM_iscachedpic,
909         VM_precache_pic,
910         VM_freepic,
911         VM_drawcharacter,
912         VM_drawstring,
913         VM_drawpic,
914         VM_drawfill,
915         VM_drawsetcliparea,
916         VM_drawresetcliparea,
917         VM_getimagesize,// 460
918         VM_cin_open,
919         VM_cin_close,
920         VM_cin_setstate,
921         VM_cin_getstate,
922         VM_cin_restart, // 465
923         VM_drawline,    // 466
924         0,0,0,0,        // 470
925         VM_asin,                                        // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
926         VM_acos,                                        // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
927         VM_atan,                                        // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
928         VM_atan2,                                       // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
929         VM_tan,                                         // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
930         VM_strlennocol,                         // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
931         VM_strdecolorize,                       // #477 string(string s) : DRESK - Decolorized String (DP_QC_STRINGCOLORFUNCTIONS)
932         0,0,0,                  // 480
933         e10,                    // 490
934         e10,                    // 500
935         e100,                   // 600
936         // menu functions
937         VM_M_setkeydest,
938         VM_M_getkeydest,
939         VM_M_setmousetarget,
940         VM_M_getmousetarget,
941         VM_M_callfunction,
942         VM_M_writetofile,
943         VM_M_isfunction,
944         VM_M_getresolution,
945         VM_keynumtostring,
946         VM_M_findkeysforcommand,// 610
947         VM_M_getserverliststat,
948         VM_M_getserverliststring,
949         VM_parseentitydata,
950         VM_stringtokeynum,
951         VM_M_resetserverlistmasks,
952         VM_M_setserverlistmaskstring,
953         VM_M_setserverlistmasknumber,
954         VM_M_resortserverlist,
955         VM_M_setserverlistsort,
956         VM_M_refreshserverlist,
957         VM_M_getserverlistnumber,
958         VM_M_getserverlistindexforkey,
959         VM_M_addwantedserverlistkey, // 623
960         VM_M_getextresponse
961 };
962
963 const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
964
965 void VM_M_Cmd_Init(void)
966 {
967         VM_Cmd_Init();
968 }
969
970 void VM_M_Cmd_Reset(void)
971 {
972         //VM_Cmd_Init();
973         VM_Cmd_Reset();
974 }