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