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