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