1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4
5 This file is part of Quake III Arena source code.
6
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 ===========================================================================
21 */
22
23 #include "client.h"
24
25 #include "../botlib/botlib.h"
26
27 extern botlib_export_t *botlib_export;
28
29 vm_t *uivm;
30
31 /*
32 ====================
33 GetClientState
34 ====================
35 */
GetClientState(uiClientState_t * state)36 static void GetClientState( uiClientState_t *state ) {
37 state->connectPacketCount = clc.connectPacketCount;
38 state->connState = cls.state;
39 Q_strncpyz( state->servername, cls.servername, sizeof( state->servername ) );
40 Q_strncpyz( state->updateInfoString, cls.updateInfoString, sizeof( state->updateInfoString ) );
41 Q_strncpyz( state->messageString, clc.serverMessage, sizeof( state->messageString ) );
42 state->clientNum = cl.snap.ps.clientNum;
43 }
44
45 /*
46 ====================
47 LAN_LoadCachedServers
48 ====================
49 */
LAN_LoadCachedServers(void)50 void LAN_LoadCachedServers( void ) {
51 int size;
52 fileHandle_t fileIn;
53 cls.numglobalservers = cls.numfavoriteservers = 0;
54 cls.numGlobalServerAddresses = 0;
55 if (FS_SV_FOpenFileRead("servercache.dat", &fileIn)) {
56 FS_Read(&cls.numglobalservers, sizeof(int), fileIn);
57 FS_Read(&cls.numfavoriteservers, sizeof(int), fileIn);
58 FS_Read(&size, sizeof(int), fileIn);
59 if (size == sizeof(cls.globalServers) + sizeof(cls.favoriteServers)) {
60 FS_Read(&cls.globalServers, sizeof(cls.globalServers), fileIn);
61 FS_Read(&cls.favoriteServers, sizeof(cls.favoriteServers), fileIn);
62 } else {
63 cls.numglobalservers = cls.numfavoriteservers = 0;
64 cls.numGlobalServerAddresses = 0;
65 }
66 FS_FCloseFile(fileIn);
67 }
68 }
69
70 /*
71 ====================
72 LAN_SaveServersToCache
73 ====================
74 */
LAN_SaveServersToCache(void)75 void LAN_SaveServersToCache( void ) {
76 int size;
77 fileHandle_t fileOut = FS_SV_FOpenFileWrite("servercache.dat");
78 FS_Write(&cls.numglobalservers, sizeof(int), fileOut);
79 FS_Write(&cls.numfavoriteservers, sizeof(int), fileOut);
80 size = sizeof(cls.globalServers) + sizeof(cls.favoriteServers);
81 FS_Write(&size, sizeof(int), fileOut);
82 FS_Write(&cls.globalServers, sizeof(cls.globalServers), fileOut);
83 FS_Write(&cls.favoriteServers, sizeof(cls.favoriteServers), fileOut);
84 FS_FCloseFile(fileOut);
85 }
86
87
88 /*
89 ====================
90 LAN_ResetPings
91 ====================
92 */
LAN_ResetPings(int source)93 static void LAN_ResetPings(int source) {
94 int count,i;
95 serverInfo_t *servers = NULL;
96 count = 0;
97
98 switch (source) {
99 case AS_LOCAL :
100 servers = &cls.localServers[0];
101 count = MAX_OTHER_SERVERS;
102 break;
103 case AS_MPLAYER:
104 case AS_GLOBAL :
105 servers = &cls.globalServers[0];
106 count = MAX_GLOBAL_SERVERS;
107 break;
108 case AS_FAVORITES :
109 servers = &cls.favoriteServers[0];
110 count = MAX_OTHER_SERVERS;
111 break;
112 }
113 if (servers) {
114 for (i = 0; i < count; i++) {
115 servers[i].ping = -1;
116 }
117 }
118 }
119
120 /*
121 ====================
122 LAN_AddServer
123 ====================
124 */
LAN_AddServer(int source,const char * name,const char * address)125 static int LAN_AddServer(int source, const char *name, const char *address) {
126 int max, *count, i;
127 netadr_t adr;
128 serverInfo_t *servers = NULL;
129 max = MAX_OTHER_SERVERS;
130 count = NULL;
131
132 switch (source) {
133 case AS_LOCAL :
134 count = &cls.numlocalservers;
135 servers = &cls.localServers[0];
136 break;
137 case AS_MPLAYER:
138 case AS_GLOBAL :
139 max = MAX_GLOBAL_SERVERS;
140 count = &cls.numglobalservers;
141 servers = &cls.globalServers[0];
142 break;
143 case AS_FAVORITES :
144 count = &cls.numfavoriteservers;
145 servers = &cls.favoriteServers[0];
146 break;
147 }
148 if (servers && *count < max) {
149 NET_StringToAdr( address, &adr, NA_IP );
150 for ( i = 0; i < *count; i++ ) {
151 if (NET_CompareAdr(servers[i].adr, adr)) {
152 break;
153 }
154 }
155 if (i >= *count) {
156 servers[*count].adr = adr;
157 Q_strncpyz(servers[*count].hostName, name, sizeof(servers[*count].hostName));
158 servers[*count].visible = qtrue;
159 (*count)++;
160 return 1;
161 }
162 return 0;
163 }
164 return -1;
165 }
166
167 /*
168 ====================
169 LAN_RemoveServer
170 ====================
171 */
LAN_RemoveServer(int source,const char * addr)172 static void LAN_RemoveServer(int source, const char *addr) {
173 int *count, i;
174 serverInfo_t *servers = NULL;
175 count = NULL;
176 switch (source) {
177 case AS_LOCAL :
178 count = &cls.numlocalservers;
179 servers = &cls.localServers[0];
180 break;
181 case AS_MPLAYER:
182 case AS_GLOBAL :
183 count = &cls.numglobalservers;
184 servers = &cls.globalServers[0];
185 break;
186 case AS_FAVORITES :
187 count = &cls.numfavoriteservers;
188 servers = &cls.favoriteServers[0];
189 break;
190 }
191 if (servers) {
192 netadr_t comp;
193 NET_StringToAdr( addr, &comp, NA_IP );
194 for (i = 0; i < *count; i++) {
195 if (NET_CompareAdr( comp, servers[i].adr)) {
196 int j = i;
197 while (j < *count - 1) {
198 Com_Memcpy(&servers[j], &servers[j+1], sizeof(servers[j]));
199 j++;
200 }
201 (*count)--;
202 break;
203 }
204 }
205 }
206 }
207
208
209 /*
210 ====================
211 LAN_GetServerCount
212 ====================
213 */
LAN_GetServerCount(int source)214 static int LAN_GetServerCount( int source ) {
215 switch (source) {
216 case AS_LOCAL :
217 return cls.numlocalservers;
218 break;
219 case AS_MPLAYER:
220 case AS_GLOBAL :
221 return cls.numglobalservers;
222 break;
223 case AS_FAVORITES :
224 return cls.numfavoriteservers;
225 break;
226 }
227 return 0;
228 }
229
230 /*
231 ====================
232 LAN_GetLocalServerAddressString
233 ====================
234 */
LAN_GetServerAddressString(int source,int n,char * buf,int buflen)235 static void LAN_GetServerAddressString( int source, int n, char *buf, int buflen ) {
236 switch (source) {
237 case AS_LOCAL :
238 if (n >= 0 && n < MAX_OTHER_SERVERS) {
239 Q_strncpyz(buf, NET_AdrToStringwPort( cls.localServers[n].adr) , buflen );
240 return;
241 }
242 break;
243 case AS_MPLAYER:
244 case AS_GLOBAL :
245 if (n >= 0 && n < MAX_GLOBAL_SERVERS) {
246 Q_strncpyz(buf, NET_AdrToStringwPort( cls.globalServers[n].adr) , buflen );
247 return;
248 }
249 break;
250 case AS_FAVORITES :
251 if (n >= 0 && n < MAX_OTHER_SERVERS) {
252 Q_strncpyz(buf, NET_AdrToStringwPort( cls.favoriteServers[n].adr) , buflen );
253 return;
254 }
255 break;
256 }
257 buf[0] = '\0';
258 }
259
260 /*
261 ====================
262 LAN_GetServerInfo
263 ====================
264 */
LAN_GetServerInfo(int source,int n,char * buf,int buflen)265 static void LAN_GetServerInfo( int source, int n, char *buf, int buflen ) {
266 char info[MAX_STRING_CHARS];
267 serverInfo_t *server = NULL;
268 info[0] = '\0';
269 switch (source) {
270 case AS_LOCAL :
271 if (n >= 0 && n < MAX_OTHER_SERVERS) {
272 server = &cls.localServers[n];
273 }
274 break;
275 case AS_MPLAYER:
276 case AS_GLOBAL :
277 if (n >= 0 && n < MAX_GLOBAL_SERVERS) {
278 server = &cls.globalServers[n];
279 }
280 break;
281 case AS_FAVORITES :
282 if (n >= 0 && n < MAX_OTHER_SERVERS) {
283 server = &cls.favoriteServers[n];
284 }
285 break;
286 }
287 if (server && buf) {
288 buf[0] = '\0';
289 Info_SetValueForKey( info, "hostname", server->hostName);
290 Info_SetValueForKey( info, "mapname", server->mapName);
291 Info_SetValueForKey( info, "clients", va("%i",server->clients));
292 Info_SetValueForKey( info, "sv_maxclients", va("%i",server->maxClients));
293 Info_SetValueForKey( info, "ping", va("%i",server->ping));
294 Info_SetValueForKey( info, "minping", va("%i",server->minPing));
295 Info_SetValueForKey( info, "maxping", va("%i",server->maxPing));
296 Info_SetValueForKey( info, "game", server->game);
297 Info_SetValueForKey( info, "gametype", va("%i",server->gameType));
298 Info_SetValueForKey( info, "nettype", va("%i",server->netType));
299 Info_SetValueForKey( info, "addr", NET_AdrToString(server->adr));
300 Info_SetValueForKey( info, "punkbuster", va("%i", server->punkbuster));
301 Q_strncpyz(buf, info, buflen);
302 } else {
303 if (buf) {
304 buf[0] = '\0';
305 }
306 }
307 }
308
309 /*
310 ====================
311 LAN_GetServerPing
312 ====================
313 */
LAN_GetServerPing(int source,int n)314 static int LAN_GetServerPing( int source, int n ) {
315 serverInfo_t *server = NULL;
316 switch (source) {
317 case AS_LOCAL :
318 if (n >= 0 && n < MAX_OTHER_SERVERS) {
319 server = &cls.localServers[n];
320 }
321 break;
322 case AS_MPLAYER:
323 case AS_GLOBAL :
324 if (n >= 0 && n < MAX_GLOBAL_SERVERS) {
325 server = &cls.globalServers[n];
326 }
327 break;
328 case AS_FAVORITES :
329 if (n >= 0 && n < MAX_OTHER_SERVERS) {
330 server = &cls.favoriteServers[n];
331 }
332 break;
333 }
334 if (server) {
335 return server->ping;
336 }
337 return -1;
338 }
339
340 /*
341 ====================
342 LAN_GetServerPtr
343 ====================
344 */
LAN_GetServerPtr(int source,int n)345 static serverInfo_t *LAN_GetServerPtr( int source, int n ) {
346 switch (source) {
347 case AS_LOCAL :
348 if (n >= 0 && n < MAX_OTHER_SERVERS) {
349 return &cls.localServers[n];
350 }
351 break;
352 case AS_MPLAYER:
353 case AS_GLOBAL :
354 if (n >= 0 && n < MAX_GLOBAL_SERVERS) {
355 return &cls.globalServers[n];
356 }
357 break;
358 case AS_FAVORITES :
359 if (n >= 0 && n < MAX_OTHER_SERVERS) {
360 return &cls.favoriteServers[n];
361 }
362 break;
363 }
364 return NULL;
365 }
366
367 /*
368 ====================
369 LAN_CompareServers
370 ====================
371 */
LAN_CompareServers(int source,int sortKey,int sortDir,int s1,int s2)372 static int LAN_CompareServers( int source, int sortKey, int sortDir, int s1, int s2 ) {
373 int res;
374 serverInfo_t *server1, *server2;
375
376 server1 = LAN_GetServerPtr(source, s1);
377 server2 = LAN_GetServerPtr(source, s2);
378 if (!server1 || !server2) {
379 return 0;
380 }
381
382 res = 0;
383 switch( sortKey ) {
384 case SORT_HOST:
385 res = Q_stricmp( server1->hostName, server2->hostName );
386 break;
387
388 case SORT_MAP:
389 res = Q_stricmp( server1->mapName, server2->mapName );
390 break;
391 case SORT_CLIENTS:
392 if (server1->clients < server2->clients) {
393 res = -1;
394 }
395 else if (server1->clients > server2->clients) {
396 res = 1;
397 }
398 else {
399 res = 0;
400 }
401 break;
402 case SORT_GAME:
403 if (server1->gameType < server2->gameType) {
404 res = -1;
405 }
406 else if (server1->gameType > server2->gameType) {
407 res = 1;
408 }
409 else {
410 res = 0;
411 }
412 break;
413 case SORT_PING:
414 if (server1->ping < server2->ping) {
415 res = -1;
416 }
417 else if (server1->ping > server2->ping) {
418 res = 1;
419 }
420 else {
421 res = 0;
422 }
423 break;
424 }
425
426 if (sortDir) {
427 if (res < 0)
428 return 1;
429 if (res > 0)
430 return -1;
431 return 0;
432 }
433 return res;
434 }
435
436 /*
437 ====================
438 LAN_GetPingQueueCount
439 ====================
440 */
LAN_GetPingQueueCount(void)441 static int LAN_GetPingQueueCount( void ) {
442 return (CL_GetPingQueueCount());
443 }
444
445 /*
446 ====================
447 LAN_ClearPing
448 ====================
449 */
LAN_ClearPing(int n)450 static void LAN_ClearPing( int n ) {
451 CL_ClearPing( n );
452 }
453
454 /*
455 ====================
456 LAN_GetPing
457 ====================
458 */
LAN_GetPing(int n,char * buf,int buflen,int * pingtime)459 static void LAN_GetPing( int n, char *buf, int buflen, int *pingtime ) {
460 CL_GetPing( n, buf, buflen, pingtime );
461 }
462
463 /*
464 ====================
465 LAN_GetPingInfo
466 ====================
467 */
LAN_GetPingInfo(int n,char * buf,int buflen)468 static void LAN_GetPingInfo( int n, char *buf, int buflen ) {
469 CL_GetPingInfo( n, buf, buflen );
470 }
471
472 /*
473 ====================
474 LAN_MarkServerVisible
475 ====================
476 */
LAN_MarkServerVisible(int source,int n,qboolean visible)477 static void LAN_MarkServerVisible(int source, int n, qboolean visible ) {
478 if (n == -1) {
479 int count = MAX_OTHER_SERVERS;
480 serverInfo_t *server = NULL;
481 switch (source) {
482 case AS_LOCAL :
483 server = &cls.localServers[0];
484 break;
485 case AS_MPLAYER:
486 case AS_GLOBAL :
487 server = &cls.globalServers[0];
488 count = MAX_GLOBAL_SERVERS;
489 break;
490 case AS_FAVORITES :
491 server = &cls.favoriteServers[0];
492 break;
493 }
494 if (server) {
495 for (n = 0; n < count; n++) {
496 server[n].visible = visible;
497 }
498 }
499
500 } else {
501 switch (source) {
502 case AS_LOCAL :
503 if (n >= 0 && n < MAX_OTHER_SERVERS) {
504 cls.localServers[n].visible = visible;
505 }
506 break;
507 case AS_MPLAYER:
508 case AS_GLOBAL :
509 if (n >= 0 && n < MAX_GLOBAL_SERVERS) {
510 cls.globalServers[n].visible = visible;
511 }
512 break;
513 case AS_FAVORITES :
514 if (n >= 0 && n < MAX_OTHER_SERVERS) {
515 cls.favoriteServers[n].visible = visible;
516 }
517 break;
518 }
519 }
520 }
521
522
523 /*
524 =======================
525 LAN_ServerIsVisible
526 =======================
527 */
LAN_ServerIsVisible(int source,int n)528 static int LAN_ServerIsVisible(int source, int n ) {
529 switch (source) {
530 case AS_LOCAL :
531 if (n >= 0 && n < MAX_OTHER_SERVERS) {
532 return cls.localServers[n].visible;
533 }
534 break;
535 case AS_MPLAYER:
536 case AS_GLOBAL :
537 if (n >= 0 && n < MAX_GLOBAL_SERVERS) {
538 return cls.globalServers[n].visible;
539 }
540 break;
541 case AS_FAVORITES :
542 if (n >= 0 && n < MAX_OTHER_SERVERS) {
543 return cls.favoriteServers[n].visible;
544 }
545 break;
546 }
547 return qfalse;
548 }
549
550 /*
551 =======================
552 LAN_UpdateVisiblePings
553 =======================
554 */
LAN_UpdateVisiblePings(int source)555 qboolean LAN_UpdateVisiblePings(int source ) {
556 return CL_UpdateVisiblePings_f(source);
557 }
558
559 /*
560 ====================
561 LAN_GetServerStatus
562 ====================
563 */
LAN_GetServerStatus(char * serverAddress,char * serverStatus,int maxLen)564 int LAN_GetServerStatus( char *serverAddress, char *serverStatus, int maxLen ) {
565 return CL_ServerStatus( serverAddress, serverStatus, maxLen );
566 }
567
568 /*
569 ====================
570 CL_GetGlConfig
571 ====================
572 */
CL_GetGlconfig(glConfig_t * config)573 static void CL_GetGlconfig( glConfig_t *config ) {
574 *config = cls.glconfig;
575 }
576
577 /*
578 ====================
579 CL_GetClipboardData
580 ====================
581 */
CL_GetClipboardData(char * buf,int buflen)582 static void CL_GetClipboardData( char *buf, int buflen ) {
583 char *cbd;
584
585 cbd = Sys_GetClipboardData();
586
587 if ( !cbd ) {
588 *buf = 0;
589 return;
590 }
591
592 Q_strncpyz( buf, cbd, buflen );
593
594 Z_Free( cbd );
595 }
596
597 /*
598 ====================
599 Key_KeynumToStringBuf
600 ====================
601 */
Key_KeynumToStringBuf(int keynum,char * buf,int buflen)602 static void Key_KeynumToStringBuf( int keynum, char *buf, int buflen ) {
603 Q_strncpyz( buf, Key_KeynumToString( keynum ), buflen );
604 }
605
606 /*
607 ====================
608 Key_GetBindingBuf
609 ====================
610 */
Key_GetBindingBuf(int keynum,char * buf,int buflen)611 static void Key_GetBindingBuf( int keynum, char *buf, int buflen ) {
612 char *value;
613
614 value = Key_GetBinding( keynum );
615 if ( value ) {
616 Q_strncpyz( buf, value, buflen );
617 }
618 else {
619 *buf = 0;
620 }
621 }
622
623 /*
624 ====================
625 CLUI_GetCDKey
626 ====================
627 */
628 #ifndef STANDALONE
CLUI_GetCDKey(char * buf,int buflen)629 static void CLUI_GetCDKey( char *buf, int buflen ) {
630 cvar_t *fs;
631 fs = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
632 if (UI_usesUniqueCDKey() && fs && fs->string[0] != 0) {
633 Com_Memcpy( buf, &cl_cdkey[16], 16);
634 buf[16] = 0;
635 } else {
636 Com_Memcpy( buf, cl_cdkey, 16);
637 buf[16] = 0;
638 }
639 }
640
641
642 /*
643 ====================
644 CLUI_SetCDKey
645 ====================
646 */
CLUI_SetCDKey(char * buf)647 static void CLUI_SetCDKey( char *buf ) {
648 cvar_t *fs;
649 fs = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
650 if (UI_usesUniqueCDKey() && fs && fs->string[0] != 0) {
651 Com_Memcpy( &cl_cdkey[16], buf, 16 );
652 cl_cdkey[32] = 0;
653 // set the flag so the fle will be written at the next opportunity
654 cvar_modifiedFlags |= CVAR_ARCHIVE;
655 } else {
656 Com_Memcpy( cl_cdkey, buf, 16 );
657 // set the flag so the fle will be written at the next opportunity
658 cvar_modifiedFlags |= CVAR_ARCHIVE;
659 }
660 }
661 #endif
662
663 /*
664 ====================
665 GetConfigString
666 ====================
667 */
GetConfigString(int index,char * buf,int size)668 static int GetConfigString(int index, char *buf, int size)
669 {
670 int offset;
671
672 if (index < 0 || index >= MAX_CONFIGSTRINGS)
673 return qfalse;
674
675 offset = cl.gameState.stringOffsets[index];
676 if (!offset) {
677 if( size ) {
678 buf[0] = 0;
679 }
680 return qfalse;
681 }
682
683 Q_strncpyz( buf, cl.gameState.stringData+offset, size);
684
685 return qtrue;
686 }
687
688 /*
689 ====================
690 FloatAsInt
691 ====================
692 */
FloatAsInt(float f)693 static int FloatAsInt( float f ) {
694 int temp;
695
696 *(float *)&temp = f;
697
698 return temp;
699 }
700
701 /*
702 ====================
703 CL_UISystemCalls
704
705 The ui module is making a system call
706 ====================
707 */
CL_UISystemCalls(intptr_t * args)708 intptr_t CL_UISystemCalls( intptr_t *args ) {
709 switch( args[0] ) {
710 case UI_ERROR:
711 Com_Error( ERR_DROP, "%s", (const char*)VMA(1) );
712 return 0;
713
714 case UI_PRINT:
715 Com_Printf( "%s", (const char*)VMA(1) );
716 return 0;
717
718 case UI_MILLISECONDS:
719 return Sys_Milliseconds();
720
721 case UI_CVAR_REGISTER:
722 Cvar_Register( VMA(1), VMA(2), VMA(3), args[4] );
723 return 0;
724
725 case UI_CVAR_UPDATE:
726 Cvar_Update( VMA(1) );
727 return 0;
728
729 case UI_CVAR_SET:
730 Cvar_Set( VMA(1), VMA(2) );
731 return 0;
732
733 case UI_CVAR_VARIABLEVALUE:
734 return FloatAsInt( Cvar_VariableValue( VMA(1) ) );
735
736 case UI_CVAR_VARIABLESTRINGBUFFER:
737 Cvar_VariableStringBuffer( VMA(1), VMA(2), args[3] );
738 return 0;
739
740 case UI_CVAR_SETVALUE:
741 Cvar_SetValue( VMA(1), VMF(2) );
742 return 0;
743
744 case UI_CVAR_RESET:
745 Cvar_Reset( VMA(1) );
746 return 0;
747
748 case UI_CVAR_CREATE:
749 Cvar_Get( VMA(1), VMA(2), args[3] );
750 return 0;
751
752 case UI_CVAR_INFOSTRINGBUFFER:
753 Cvar_InfoStringBuffer( args[1], VMA(2), args[3] );
754 return 0;
755
756 case UI_ARGC:
757 return Cmd_Argc();
758
759 case UI_ARGV:
760 Cmd_ArgvBuffer( args[1], VMA(2), args[3] );
761 return 0;
762
763 case UI_CMD_EXECUTETEXT:
764 if(args[1] == 0
765 && (!strncmp(VMA(2), "snd_restart", 11)
766 || !strncmp(VMA(2), "vid_restart", 11)
767 || !strncmp(VMA(2), "quit", 5)))
768 {
769 Com_Printf (S_COLOR_YELLOW "turning EXEC_NOW '%.11s' into EXEC_INSERT\n", (const char*)VMA(2));
770 args[1] = EXEC_INSERT;
771 }
772 Cbuf_ExecuteText( args[1], VMA(2) );
773 return 0;
774
775 case UI_FS_FOPENFILE:
776 return FS_FOpenFileByMode( VMA(1), VMA(2), args[3] );
777
778 case UI_FS_READ:
779 FS_Read2( VMA(1), args[2], args[3] );
780 return 0;
781
782 case UI_FS_WRITE:
783 FS_Write( VMA(1), args[2], args[3] );
784 return 0;
785
786 case UI_FS_FCLOSEFILE:
787 FS_FCloseFile( args[1] );
788 return 0;
789
790 case UI_FS_GETFILELIST:
791 return FS_GetFileList( VMA(1), VMA(2), VMA(3), args[4] );
792
793 case UI_FS_SEEK:
794 return FS_Seek( args[1], args[2], args[3] );
795
796 case UI_R_REGISTERMODEL:
797 return re.RegisterModel( VMA(1) );
798
799 case UI_R_REGISTERSKIN:
800 return re.RegisterSkin( VMA(1) );
801
802 case UI_R_REGISTERSHADERNOMIP:
803 return re.RegisterShaderNoMip( VMA(1) );
804
805 case UI_R_CLEARSCENE:
806 re.ClearScene();
807 return 0;
808
809 case UI_R_ADDREFENTITYTOSCENE:
810 re.AddRefEntityToScene( VMA(1) );
811 return 0;
812
813 case UI_R_ADDPOLYTOSCENE:
814 re.AddPolyToScene( args[1], args[2], VMA(3), 1 );
815 return 0;
816
817 case UI_R_ADDLIGHTTOSCENE:
818 re.AddLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
819 return 0;
820
821 case UI_R_RENDERSCENE:
822 re.RenderScene( VMA(1) );
823 return 0;
824
825 case UI_R_SETCOLOR:
826 re.SetColor( VMA(1) );
827 return 0;
828
829 case UI_R_DRAWSTRETCHPIC:
830 re.DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9] );
831 return 0;
832
833 case UI_R_MODELBOUNDS:
834 re.ModelBounds( args[1], VMA(2), VMA(3) );
835 return 0;
836
837 case UI_UPDATESCREEN:
838 SCR_UpdateScreen();
839 return 0;
840
841 case UI_CM_LERPTAG:
842 re.LerpTag( VMA(1), args[2], args[3], args[4], VMF(5), VMA(6) );
843 return 0;
844
845 case UI_S_REGISTERSOUND:
846 return S_RegisterSound( VMA(1), args[2] );
847
848 case UI_S_STARTLOCALSOUND:
849 S_StartLocalSound( args[1], args[2] );
850 return 0;
851
852 case UI_KEY_KEYNUMTOSTRINGBUF:
853 Key_KeynumToStringBuf( args[1], VMA(2), args[3] );
854 return 0;
855
856 case UI_KEY_GETBINDINGBUF:
857 Key_GetBindingBuf( args[1], VMA(2), args[3] );
858 return 0;
859
860 case UI_KEY_SETBINDING:
861 Key_SetBinding( args[1], VMA(2) );
862 return 0;
863
864 case UI_KEY_ISDOWN:
865 return Key_IsDown( args[1] );
866
867 case UI_KEY_GETOVERSTRIKEMODE:
868 return Key_GetOverstrikeMode();
869
870 case UI_KEY_SETOVERSTRIKEMODE:
871 Key_SetOverstrikeMode( args[1] );
872 return 0;
873
874 case UI_KEY_CLEARSTATES:
875 Key_ClearStates();
876 return 0;
877
878 case UI_KEY_GETCATCHER:
879 return Key_GetCatcher();
880
881 case UI_KEY_SETCATCHER:
882 // Don't allow the ui module to close the console
883 Key_SetCatcher( args[1] | ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) );
884 return 0;
885
886 case UI_GETCLIPBOARDDATA:
887 CL_GetClipboardData( VMA(1), args[2] );
888 return 0;
889
890 case UI_GETCLIENTSTATE:
891 GetClientState( VMA(1) );
892 return 0;
893
894 case UI_GETGLCONFIG:
895 CL_GetGlconfig( VMA(1) );
896 return 0;
897
898 case UI_GETCONFIGSTRING:
899 return GetConfigString( args[1], VMA(2), args[3] );
900
901 case UI_LAN_LOADCACHEDSERVERS:
902 LAN_LoadCachedServers();
903 return 0;
904
905 case UI_LAN_SAVECACHEDSERVERS:
906 LAN_SaveServersToCache();
907 return 0;
908
909 case UI_LAN_ADDSERVER:
910 return LAN_AddServer(args[1], VMA(2), VMA(3));
911
912 case UI_LAN_REMOVESERVER:
913 LAN_RemoveServer(args[1], VMA(2));
914 return 0;
915
916 case UI_LAN_GETPINGQUEUECOUNT:
917 return LAN_GetPingQueueCount();
918
919 case UI_LAN_CLEARPING:
920 LAN_ClearPing( args[1] );
921 return 0;
922
923 case UI_LAN_GETPING:
924 LAN_GetPing( args[1], VMA(2), args[3], VMA(4) );
925 return 0;
926
927 case UI_LAN_GETPINGINFO:
928 LAN_GetPingInfo( args[1], VMA(2), args[3] );
929 return 0;
930
931 case UI_LAN_GETSERVERCOUNT:
932 return LAN_GetServerCount(args[1]);
933
934 case UI_LAN_GETSERVERADDRESSSTRING:
935 LAN_GetServerAddressString( args[1], args[2], VMA(3), args[4] );
936 return 0;
937
938 case UI_LAN_GETSERVERINFO:
939 LAN_GetServerInfo( args[1], args[2], VMA(3), args[4] );
940 return 0;
941
942 case UI_LAN_GETSERVERPING:
943 return LAN_GetServerPing( args[1], args[2] );
944
945 case UI_LAN_MARKSERVERVISIBLE:
946 LAN_MarkServerVisible( args[1], args[2], args[3] );
947 return 0;
948
949 case UI_LAN_SERVERISVISIBLE:
950 return LAN_ServerIsVisible( args[1], args[2] );
951
952 case UI_LAN_UPDATEVISIBLEPINGS:
953 return LAN_UpdateVisiblePings( args[1] );
954
955 case UI_LAN_RESETPINGS:
956 LAN_ResetPings( args[1] );
957 return 0;
958
959 case UI_LAN_SERVERSTATUS:
960 return LAN_GetServerStatus( VMA(1), VMA(2), args[3] );
961
962 case UI_LAN_COMPARESERVERS:
963 return LAN_CompareServers( args[1], args[2], args[3], args[4], args[5] );
964
965 case UI_MEMORY_REMAINING:
966 return Hunk_MemoryRemaining();
967
968 #ifndef STANDALONE
969 case UI_GET_CDKEY:
970 CLUI_GetCDKey( VMA(1), args[2] );
971 return 0;
972
973 case UI_SET_CDKEY:
974 CLUI_SetCDKey( VMA(1) );
975 return 0;
976 #endif
977
978 case UI_SET_PBCLSTATUS:
979 return 0;
980
981 case UI_R_REGISTERFONT:
982 re.RegisterFont( VMA(1), args[2], VMA(3));
983 return 0;
984
985 case UI_MEMSET:
986 Com_Memset( VMA(1), args[2], args[3] );
987 return 0;
988
989 case UI_MEMCPY:
990 Com_Memcpy( VMA(1), VMA(2), args[3] );
991 return 0;
992
993 case UI_STRNCPY:
994 strncpy( VMA(1), VMA(2), args[3] );
995 return args[1];
996
997 case UI_SIN:
998 return FloatAsInt( sin( VMF(1) ) );
999
1000 case UI_COS:
1001 return FloatAsInt( cos( VMF(1) ) );
1002
1003 case UI_ATAN2:
1004 return FloatAsInt( atan2( VMF(1), VMF(2) ) );
1005
1006 case UI_SQRT:
1007 return FloatAsInt( sqrt( VMF(1) ) );
1008
1009 case UI_FLOOR:
1010 return FloatAsInt( floor( VMF(1) ) );
1011
1012 case UI_CEIL:
1013 return FloatAsInt( ceil( VMF(1) ) );
1014
1015 case UI_PC_ADD_GLOBAL_DEFINE:
1016 return botlib_export->PC_AddGlobalDefine( VMA(1) );
1017 case UI_PC_LOAD_SOURCE:
1018 return botlib_export->PC_LoadSourceHandle( VMA(1) );
1019 case UI_PC_FREE_SOURCE:
1020 return botlib_export->PC_FreeSourceHandle( args[1] );
1021 case UI_PC_READ_TOKEN:
1022 return botlib_export->PC_ReadTokenHandle( args[1], VMA(2) );
1023 case UI_PC_SOURCE_FILE_AND_LINE:
1024 return botlib_export->PC_SourceFileAndLine( args[1], VMA(2), VMA(3) );
1025
1026 case UI_S_STOPBACKGROUNDTRACK:
1027 S_StopBackgroundTrack();
1028 return 0;
1029 case UI_S_STARTBACKGROUNDTRACK:
1030 S_StartBackgroundTrack( VMA(1), VMA(2));
1031 return 0;
1032
1033 case UI_REAL_TIME:
1034 return Com_RealTime( VMA(1) );
1035
1036 case UI_CIN_PLAYCINEMATIC:
1037 Com_DPrintf("UI_CIN_PlayCinematic\n");
1038 return CIN_PlayCinematic(VMA(1), args[2], args[3], args[4], args[5], args[6]);
1039
1040 case UI_CIN_STOPCINEMATIC:
1041 return CIN_StopCinematic(args[1]);
1042
1043 case UI_CIN_RUNCINEMATIC:
1044 return CIN_RunCinematic(args[1]);
1045
1046 case UI_CIN_DRAWCINEMATIC:
1047 CIN_DrawCinematic(args[1]);
1048 return 0;
1049
1050 case UI_CIN_SETEXTENTS:
1051 CIN_SetExtents(args[1], args[2], args[3], args[4], args[5]);
1052 return 0;
1053
1054 case UI_R_REMAP_SHADER:
1055 re.RemapShader( VMA(1), VMA(2), VMA(3) );
1056 return 0;
1057
1058 #ifndef STANDALONE
1059 case UI_VERIFY_CDKEY:
1060 return CL_CDKeyValidate(VMA(1), VMA(2));
1061 #endif
1062
1063
1064 default:
1065 Com_Error( ERR_DROP, "Bad UI system trap: %ld", (long int) args[0] );
1066
1067 }
1068
1069 return 0;
1070 }
1071
1072 /*
1073 ====================
1074 CL_ShutdownUI
1075 ====================
1076 */
CL_ShutdownUI(void)1077 void CL_ShutdownUI( void ) {
1078 Key_SetCatcher( Key_GetCatcher( ) & ~KEYCATCH_UI );
1079 cls.uiStarted = qfalse;
1080 if ( !uivm ) {
1081 return;
1082 }
1083 VM_Call( uivm, UI_SHUTDOWN );
1084 VM_Free( uivm );
1085 uivm = NULL;
1086 }
1087
1088 /*
1089 ====================
1090 CL_InitUI
1091 ====================
1092 */
1093 #define UI_OLD_API_VERSION 4
1094
CL_InitUI(void)1095 void CL_InitUI( void ) {
1096 int v;
1097 vmInterpret_t interpret;
1098
1099 // load the dll or bytecode
1100 if ( cl_connectedToPureServer != 0 ) {
1101 // if sv_pure is set we only allow qvms to be loaded
1102 interpret = VMI_COMPILED;
1103 }
1104 else {
1105 interpret = Cvar_VariableValue( "vm_ui" );
1106 }
1107 uivm = VM_Create( "ui", CL_UISystemCalls, interpret );
1108 if ( !uivm ) {
1109 Com_Error( ERR_FATAL, "VM_Create on UI failed" );
1110 }
1111
1112 // sanity check
1113 v = VM_Call( uivm, UI_GETAPIVERSION );
1114 if (v == UI_OLD_API_VERSION) {
1115 // Com_Printf(S_COLOR_YELLOW "WARNING: loading old Quake III Arena User Interface version %d\n", v );
1116 // init for this gamestate
1117 VM_Call( uivm, UI_INIT, (cls.state >= CA_AUTHORIZING && cls.state < CA_ACTIVE));
1118 }
1119 else if (v != UI_API_VERSION) {
1120 Com_Error( ERR_DROP, "User Interface is version %d, expected %d", v, UI_API_VERSION );
1121 cls.uiStarted = qfalse;
1122 }
1123 else {
1124 // init for this gamestate
1125 VM_Call( uivm, UI_INIT, (cls.state >= CA_AUTHORIZING && cls.state < CA_ACTIVE) );
1126 }
1127
1128 // reset any CVAR_CHEAT cvars registered by ui
1129 if ( !clc.demoplaying && !cl_connectedToCheatServer )
1130 Cvar_SetCheatState();
1131 }
1132
1133 #ifndef STANDALONE
UI_usesUniqueCDKey(void)1134 qboolean UI_usesUniqueCDKey( void ) {
1135 if (uivm) {
1136 return (VM_Call( uivm, UI_HASUNIQUECDKEY) == qtrue);
1137 } else {
1138 return qfalse;
1139 }
1140 }
1141 #endif
1142
1143 /*
1144 ====================
1145 UI_GameCommand
1146
1147 See if the current console command is claimed by the ui
1148 ====================
1149 */
UI_GameCommand(void)1150 qboolean UI_GameCommand( void ) {
1151 if ( !uivm ) {
1152 return qfalse;
1153 }
1154
1155 return VM_Call( uivm, UI_CONSOLE_COMMAND, cls.realtime );
1156 }
1157