1 /*
2 Copyright (C) 2003-2006 Andrey Nazarov
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21 #include "ui_local.h"
22
23 #ifndef UI_HARD_LINKED
24 /* declare imports for this module */
25 cmdAPI_t cmd;
26 cvarAPI_t cvar;
27 fsAPI_t fs;
28 commonAPI_t com;
29 sysAPI_t sys;
30 refAPI_t ref;
31 keyAPI_t keys;
32 clientAPI_t client;
33 #endif
34
35 uiStatic_t uis;
36
37 cvar_t *ui_debug;
38 cvar_t *ui_open;
39 cvar_t *ui_background;
40
41 // ===========================================================================
42
EmptyCallback(int id,int msg,int param)43 static int EmptyCallback( int id, int msg, int param ) {
44 return QMS_NOTHANDLED;
45 }
46
47 /*
48 =================
49 UI_PushMenu
50 =================
51 */
UI_PushMenu(menuFrameWork_t * menu)52 void UI_PushMenu( menuFrameWork_t *menu ) {
53 int i, keydest;
54
55 cvar.Set( "cl_paused", "1" );
56
57 // if this menu is already present, drop back to that level
58 // to avoid stacking menus by hotkeys
59 for( i=0 ; i<uis.menuDepth ; i++ ) {
60 if( uis.layers[i] == menu ) {
61 break;
62 }
63 }
64
65 if( i == uis.menuDepth ) {
66 if( uis.menuDepth >= MAX_MENU_DEPTH )
67 Com_Error( ERR_FATAL, "UI_PushMenu: MAX_MENU_DEPTH" );
68 uis.layers[uis.menuDepth++] = menu;
69 } else {
70 uis.menuDepth = i;
71 }
72
73 for( i=uis.menuDepth-1 ; i>=0 ; i-- ) {
74 if( uis.layers[i]->transparent ) {
75 break;
76 }
77 }
78
79 uis.transparent = qtrue;
80 if( i < 0 ) {
81 uis.transparent = qfalse;
82 }
83
84 if( !menu->callback ) {
85 menu->callback = EmptyCallback;
86 }
87
88 if( !uis.activeMenu ) {
89 uis.entersound = qtrue;
90 }
91
92 uis.activeMenu = menu;
93
94 keydest = keys.GetDest();
95 if( keydest & KEY_CONSOLE ) {
96 keydest &= ~KEY_CONSOLE;
97 cmd.ExecuteText( EXEC_NOW, "toggleconsole\n" );
98 }
99 keys.SetDest( keydest | KEY_MENU );
100
101 UI_DoHitTest();
102 }
103
104 /*
105 =================
106 UI_ForceMenuOff
107 =================
108 */
UI_ForceMenuOff(void)109 void UI_ForceMenuOff( void ) {
110 int i;
111
112 for( i=0 ; i<uis.menuDepth ; i++ ) {
113 if( uis.layers[i] ) {
114 uis.layers[i]->callback( ID_MENU, QM_DESTROY, qtrue );
115 }
116 }
117
118 keys.SetDest( keys.GetDest() & ~KEY_MENU );
119 uis.menuDepth = 0;
120 uis.activeMenu = NULL;
121 uis.transparent = qfalse;
122 //keys.ClearStates();
123 cvar.Set( "cl_paused", "0" );
124 }
125
126 /*
127 =================
128 UI_PopMenu
129 =================
130 */
UI_PopMenu(void)131 void UI_PopMenu( void ) {
132 int i;
133
134 if( uis.menuDepth < 1 )
135 Com_Error( ERR_FATAL, "UI_PopMenu: depth < 1" );
136
137 if( --uis.menuDepth == 0 ) {
138 UI_ForceMenuOff();
139 return;
140 }
141
142 uis.layers[uis.menuDepth]->callback( ID_MENU, QM_DESTROY, qfalse );
143 uis.layers[uis.menuDepth - 1]->callback( ID_MENU, QM_DESTROY_CHILD, qfalse );
144
145 uis.activeMenu = uis.layers[uis.menuDepth - 1];
146
147 for( i=uis.menuDepth-1 ; i>=0 ; i-- ) {
148 if( uis.layers[i]->transparent ) {
149 break;
150 }
151 }
152
153 uis.transparent = qtrue;
154 if( i < 0 ) {
155 uis.transparent = qfalse;
156 }
157
158 UI_DoHitTest();
159
160
161 }
162
163 /*
164 =================
165 UI_IsTransparent
166 =================
167 */
UI_IsTransparent(void)168 qboolean UI_IsTransparent( void ) {
169 if( !( keys.GetDest() & KEY_MENU ) ) {
170 return qtrue;
171 }
172
173 if( !uis.activeMenu ) {
174 return qtrue;
175 }
176
177 return uis.transparent;
178 }
179
180 /*
181 =================
182 UI_OpenMenu
183 =================
184 */
UI_OpenMenu(uiMenu_t menu)185 void UI_OpenMenu( uiMenu_t menu ) {
186 // close any existing menus
187 UI_ForceMenuOff();
188
189 switch( menu ) {
190 case UIMENU_MAIN:
191 if( ui_open->integer ) {
192 M_Menu_Main_f();
193 }
194 break;
195 case UIMENU_MAIN_FORCE:
196 M_Menu_Main_f();
197 break;
198 case UIMENU_INGAME:
199 M_Menu_Ingame_f();
200 break;
201 case UIMENU_NONE:
202 break;
203 default:
204 Com_Error( ERR_FATAL, "UI_OpenMenu: bad menu" );
205 break;
206 }
207 }
208
UI_ErrorMenu(comErrorType_t type,const char * text)209 void UI_ErrorMenu( comErrorType_t type, const char *text ) {
210 // close any existing menus
211 UI_ForceMenuOff();
212
213 if( !ui_open->integer ) {
214 return;
215 }
216
217 M_Menu_Main_f();
218 M_Menu_Error_f( type, text );
219 }
220
221
222 //=============================================================================
223
224 /*
225 =================
226 UI_FormatColumns
227 =================
228 */
UI_FormatColumns(int numArgs,...)229 char *UI_FormatColumns( int numArgs, ... ) {
230 va_list argptr;
231 char *buffer, *p;
232 int i, totalLength;
233 char *strings[MAX_COLUMNS];
234 int lengths[MAX_COLUMNS];
235
236 if( ( unsigned )numArgs > MAX_COLUMNS ) {
237 Com_Error( ERR_FATAL, "UI_FormatColumns: too many columns" );
238 }
239
240 totalLength = 0;
241
242 va_start( argptr, numArgs );
243 for( i = 0; i < numArgs; i++ ) {
244 strings[i] = va_arg( argptr, char * );
245 lengths[i] = strlen( strings[i] ) + 1;
246 totalLength += lengths[i];
247 }
248 va_end( argptr );
249
250 buffer = p = UI_Malloc( totalLength + 1 );
251 for( i = 0; i < numArgs; i++ ) {
252 memcpy( p, strings[i], lengths[i] );
253 p += lengths[i];
254 }
255
256 *p = 0;
257
258 return buffer;
259
260 }
261
262 /*
263 =================
264 UI_CopyString
265 =================
266 */
UI_CopyString(const char * in)267 char *UI_CopyString( const char *in ) {
268 char *out;
269
270 if( !in ) {
271 return NULL;
272 }
273
274 out = UI_Malloc( strlen( in ) + 1 );
275 strcpy( out, in );
276
277 return out;
278 }
279
280 /*
281 =================
282 UI_SetupDefaultBanner
283 =================
284 */
UI_SetupDefaultBanner(menuStatic_t * banner,const char * name)285 void UI_SetupDefaultBanner( menuStatic_t *banner, const char *name ) {
286 banner->generic.type = MTYPE_STATIC;
287 banner->generic.name = name;
288 banner->generic.uiFlags = UI_CENTER|UI_ALTCOLOR;
289
290 banner->generic.x = uis.glconfig.vidWidth / 2;
291 banner->generic.y = 8;
292 }
293
294 /*
295 =================
296 UI_CursorInRect
297 =================
298 */
UI_CursorInRect(vrect_t * rect,int mx,int my)299 qboolean UI_CursorInRect( vrect_t *rect, int mx, int my ) {
300 if( mx > rect->x && mx < rect->x + rect->width &&
301 my > rect->y && my < rect->y + rect->height )
302 {
303 return qtrue;
304 }
305
306 return qfalse;
307 }
308
UI_DrawString(int x,int y,const color_t color,uint32 flags,const char * string)309 void UI_DrawString( int x, int y, const color_t color, uint32 flags, const char *string ) {
310 if( color ) {
311 ref.SetColor( DRAW_COLOR_RGBA, color );
312 }
313
314 if( ( flags & UI_CENTER ) == UI_CENTER ) {
315 x -= Q_DrawStrlen( string ) * 8 / 2;
316 } else if( flags & UI_RIGHT ) {
317 x -= Q_DrawStrlen( string ) * 8;
318 }
319
320 ref.DrawString( x, y, flags, MAX_STRING_CHARS, string, uis.fontHandle );
321 if( color ) {
322 ref.SetColor( DRAW_COLOR_CLEAR, NULL );
323 }
324 }
325
UI_DrawChar(int x,int y,uint32 flags,int ch)326 void UI_DrawChar( int x, int y, uint32 flags, int ch ) {
327 ref.DrawChar( x, y, flags, ch, uis.fontHandle );
328 }
329
UI_StringDimensions(vrect_t * rc,uint32 flags,const char * string)330 void UI_StringDimensions( vrect_t *rc, uint32 flags, const char *string ) {
331 rc->height = 8;
332 rc->width = 8 * Q_DrawStrlen( string );
333
334 if( ( flags & UI_CENTER ) == UI_CENTER ) {
335 rc->x -= rc->width / 2;
336 } else if( flags & UI_RIGHT ) {
337 rc->x -= rc->width;
338 }
339 }
340
341
342 //=============================================================================
343 /* Menu Subsystem */
344
345 void M_Menu_Network_f( void );
346
347 /*
348 =================
349 UI_DoHitTest
350 =================
351 */
UI_DoHitTest(void)352 qboolean UI_DoHitTest( void ) {
353 menuCommon_t *item;
354
355 if( !uis.activeMenu ) {
356 return qfalse;
357 }
358
359 if( !( item = Menu_HitTest( uis.activeMenu, uis.mouseCoords[0], uis.mouseCoords[1] ) ) ) {
360 return qfalse;
361 }
362 if( !UI_IsItemSelectable( item ) ) {
363 return qfalse;
364 }
365
366 Menu_MouseMove( item );
367
368 if( item->flags & QMF_HASFOCUS ) {
369 return qfalse;
370 }
371
372 Menu_SetFocus( item );
373
374 return qtrue;
375 }
376
377 /*
378 =================
379 UI_MouseMove
380 =================
381 */
UI_MouseMove(int mx,int my)382 void UI_MouseMove( int mx, int my ) {
383 if( !uis.activeMenu ) {
384 return;
385 }
386
387 if( !mx && !my ) {
388 return;
389 }
390
391 uis.mouseCoords[0] += mx;
392 uis.mouseCoords[1] += my;
393
394 clamp( uis.mouseCoords[0], 0, uis.glconfig.vidWidth );
395 clamp( uis.mouseCoords[1], 0, uis.glconfig.vidHeight );
396
397 if( UI_DoHitTest() ) {
398 // TODO: add new mousemove sound
399 // cl.StartLocalSound( "misc/menu2.wav" );
400 }
401 }
402
403
404 /*
405 =================
406 UI_Draw
407 =================
408 */
UI_Draw(int realtime)409 void UI_Draw( int realtime ) {
410 int i;
411
412 uis.realtime = realtime;
413
414 if( !( keys.GetDest() & KEY_MENU ) ) {
415 return;
416 }
417
418 if( !uis.activeMenu ) {
419 return;
420 }
421
422 ref.SetColor( DRAW_COLOR_CLEAR, NULL );
423 if( uis.glconfig.renderer == GL_RENDERER_SOFTWARE ) {
424 ref.SetClipRect( DRAW_CLIP_MASK, &uis.clipRect );
425 }
426
427 if( !uis.transparent ) {
428 // no transparent menus
429 if( uis.backgroundHandle ) {
430 ref.DrawStretchPic( 0, 0, uis.glconfig.vidWidth, uis.glconfig.vidHeight,
431 uis.backgroundHandle );
432 } else {
433 ref.DrawFill( 0, 0, uis.glconfig.vidWidth, uis.glconfig.vidHeight, 0 );
434 }
435
436 if( uis.activeMenu->draw ) {
437 uis.activeMenu->draw( uis.activeMenu );
438 } else {
439 Menu_Draw( uis.activeMenu );
440 }
441 } else {
442 // draw all layers
443 for( i = 0; i < uis.menuDepth; i++ ) {
444 if( !uis.layers[i]->transparent ) {
445 if( uis.backgroundHandle ) {
446 ref.DrawStretchPic( 0, 0, uis.glconfig.vidWidth, uis.glconfig.vidHeight,
447 uis.backgroundHandle );
448 } else {
449 ref.DrawFill( 0, 0, uis.glconfig.vidWidth, uis.glconfig.vidHeight, 0 );
450 }
451 }
452
453 if( uis.layers[i]->draw ) {
454 uis.layers[i]->draw( uis.layers[i] );
455 } else {
456 Menu_Draw( uis.layers[i] );
457 }
458 }
459 }
460
461 ref.DrawStretchPic( uis.mouseCoords[0] - uis.cursorWidth / 2,
462 uis.mouseCoords[1] - uis.cursorHeight / 2,
463 uis.cursorWidth, uis.cursorHeight, uis.cursorHandle );
464
465 if( ui_debug->integer ) {
466 Menu_HitTest( uis.activeMenu, 0, 0 );
467 UI_DrawString( uis.glconfig.vidWidth - 4, 4, NULL, UI_RIGHT,
468 va( "%3i %3i", uis.mouseCoords[0], uis.mouseCoords[1] ) );
469 }
470
471 // delay playing the enter sound until after the
472 // menu has been drawn, to avoid delay while
473 // caching images
474 if( uis.entersound ) {
475 uis.entersound = qfalse;
476 client.StartLocalSound( "misc/menu1.wav" );
477 }
478
479 if( uis.glconfig.renderer == GL_RENDERER_SOFTWARE ) {
480 ref.SetClipRect( DRAW_CLIP_DISABLED, NULL );
481 }
482 ref.SetColor( DRAW_COLOR_CLEAR, NULL );
483 }
484
485 /*
486 =================
487 Default_MenuKey
488 =================
489 */
Default_MenuKey(menuFrameWork_t * m,int key)490 int Default_MenuKey( menuFrameWork_t *m, int key ) {
491 menuCommon_t *item;
492
493 switch( key ) {
494 case K_ESCAPE:
495 UI_PopMenu();
496 return QMS_OUT;
497
498 case K_KP_UPARROW:
499 case K_UPARROW:
500 return Menu_AdjustCursor( m, -1 );
501
502 case K_KP_DOWNARROW:
503 case K_DOWNARROW:
504 case K_TAB:
505 return Menu_AdjustCursor( m, 1 );
506
507 case K_KP_LEFTARROW:
508 case K_LEFTARROW:
509 case K_MWHEELDOWN:
510 return Menu_SlideItem( m, -1 );
511
512 case K_KP_RIGHTARROW:
513 case K_RIGHTARROW:
514 case K_MWHEELUP:
515 return Menu_SlideItem( m, 1 );
516
517 case K_MOUSE1:
518 case K_MOUSE2:
519 case K_MOUSE3:
520 item = Menu_HitTest( m, uis.mouseCoords[0], uis.mouseCoords[1] );
521 if( !item ) {
522 return QMS_NOTHANDLED;
523 }
524
525 if( !( item->flags & QMF_HASFOCUS ) ) {
526 return QMS_NOTHANDLED;
527 }
528
529 // fall through
530
531 case K_JOY1:
532 case K_JOY2:
533 case K_JOY3:
534 case K_JOY4:
535 case K_AUX1:
536 case K_AUX2:
537 case K_AUX3:
538 case K_AUX4:
539 case K_AUX5:
540 case K_AUX6:
541 case K_AUX7:
542 case K_AUX8:
543 case K_AUX9:
544 case K_AUX10:
545 case K_AUX11:
546 case K_AUX12:
547 case K_AUX13:
548 case K_AUX14:
549 case K_AUX15:
550 case K_AUX16:
551 case K_AUX17:
552 case K_AUX18:
553 case K_AUX19:
554 case K_AUX20:
555 case K_AUX21:
556 case K_AUX22:
557 case K_AUX23:
558 case K_AUX24:
559 case K_AUX25:
560 case K_AUX26:
561 case K_AUX27:
562 case K_AUX28:
563 case K_AUX29:
564 case K_AUX30:
565 case K_AUX31:
566 case K_AUX32:
567 case K_KP_ENTER:
568 case K_ENTER:
569 return Menu_SelectItem( m );
570 }
571
572 return QMS_NOTHANDLED;
573 }
574
575 /*
576 =================
577 UI_Keydown
578 =================
579 */
UI_Keydown(int key)580 void UI_Keydown( int key ) {
581 menuCommon_t *item;
582 int sound;
583
584 if( !uis.activeMenu ) {
585 return;
586 }
587
588 if( ( sound = uis.activeMenu->callback( ID_MENU, QM_KEY, key ) ) == QMS_NOTHANDLED ) {
589 if( ( item = Menu_ItemAtCursor( uis.activeMenu ) ) == NULL ||
590 ( sound = Menu_KeyEvent( item, key ) ) == QMS_NOTHANDLED )
591 {
592 sound = Default_MenuKey( uis.activeMenu, key );
593 }
594 }
595
596 switch( sound ) {
597 case QMS_IN:
598 client.StartLocalSound( "misc/menu1.wav" );
599 break;
600 case QMS_MOVE:
601 client.StartLocalSound( "misc/menu2.wav" );
602 break;
603 case QMS_OUT:
604 client.StartLocalSound( "misc/menu3.wav" );
605 break;
606 case QMS_BEEP:
607 client.StartLocalSound( "misc/talk1.wav" );
608 break;
609 case QMS_NOTHANDLED:
610 default:
611 break;
612 }
613
614 }
615
616 /*
617 =================
618 UI_CharEvent
619 =================
620 */
UI_CharEvent(int key)621 void UI_CharEvent( int key ) {
622 menuCommon_t *item;
623 int sound;
624
625 if( !uis.activeMenu ) {
626 return;
627 }
628
629 if( ( sound = uis.activeMenu->callback( ID_MENU, QM_CHAR, key ) ) == QMS_NOTHANDLED ) {
630 if( ( item = Menu_ItemAtCursor( uis.activeMenu ) ) == NULL ||
631 ( sound = Menu_CharEvent( item, key ) ) == QMS_NOTHANDLED )
632 {
633 return;
634 }
635 }
636
637 switch( sound ) {
638 case QMS_IN:
639 client.StartLocalSound( "misc/menu1.wav" );
640 break;
641 case QMS_MOVE:
642 client.StartLocalSound( "misc/menu2.wav" );
643 break;
644 case QMS_OUT:
645 client.StartLocalSound( "misc/menu3.wav" );
646 break;
647 case QMS_BEEP:
648 client.StartLocalSound( "misc/talk1.wav" );
649 break;
650 case QMS_NOTHANDLED:
651 default:
652 break;
653 }
654
655 }
656
657 typedef struct uicmd_s {
658 const char *name;
659 void (*func)( void );
660 } uicmd_t;
661
662 static const uicmd_t uicmds[] = {
663 { "menu_main", M_Menu_Main_f },
664 { "menu_game", M_Menu_Game_f },
665 { "menu_loadgame", M_Menu_LoadGame_f },
666 { "menu_savegame", M_Menu_SaveGame_f },
667 { "menu_addressbook", M_Menu_AddressBook_f },
668 { "menu_startserver", M_Menu_StartServer_f },
669 { "menu_dmoptions", M_Menu_DMOptions_f },
670 { "menu_playerconfig", M_Menu_PlayerConfig_f },
671 { "menu_downloadoptions", M_Menu_DownloadOptions_f },
672 { "menu_multiplayer", M_Menu_Multiplayer_f },
673 { "menu_network", M_Menu_Network_f },
674 { "menu_video", M_Menu_Video_f },
675 { "menu_options", M_Menu_Options_f },
676 { "menu_keys", M_Menu_Keys_f },
677 { "menu_quit", M_Menu_Credits_f },
678 { "menu_close", UI_ForceMenuOff },
679
680 { NULL, NULL }
681 };
682
UI_Background_OnChange(cvar_t * self,void * arg)683 static void UI_Background_OnChange( cvar_t *self, void *arg ) {
684 if( self->string[0] ) {
685 uis.backgroundHandle = ref.RegisterPic( self->string );
686 }
687 }
688
689
690 /*
691 =================
692 UI_Init
693 =================
694 */
UI_Init(void)695 qboolean UI_Init( void ) {
696 const uicmd_t *uicmd;
697
698 memset( &uis, 0, sizeof( uis ) );
699
700 for( uicmd = uicmds; uicmd->name; uicmd++ ) {
701 cmd.AddCommand( uicmd->name, uicmd->func );
702 }
703
704 ui_debug = cvar.Get( "ui_debug", "0", 0 );
705 ui_open = cvar.Get( "ui_open", "0", CVAR_ARCHIVE );
706 ui_background = cvar.Get( "ui_background", "", 0 );
707
708 ref.GetConfig( &uis.glconfig );
709 if( uis.glconfig.renderer == GL_RENDERER_SOFTWARE ) {
710 uis.clipRect.left = 0;
711 uis.clipRect.top = 0;
712 uis.clipRect.right = uis.glconfig.vidWidth;
713 uis.clipRect.bottom = uis.glconfig.vidHeight;
714 }
715
716 uis.fontHandle = ref.RegisterFont( "conchars" );
717 uis.cursorHandle = ref.RegisterPic( "ch1" );
718 ref.DrawGetPicSize( &uis.cursorWidth, &uis.cursorHeight, uis.cursorHandle );
719
720 if( uis.glconfig.renderer != GL_RENDERER_SOFTWARE ) {
721 if( ui_background->string[0] ) {
722 uis.backgroundHandle = ref.RegisterPic( ui_background->string );
723 }
724 ui_background->changedFunc = UI_Background_OnChange;
725 }
726
727 return qtrue;
728
729 }
730
731 /*
732 =================
733 UI_Shutdown
734 =================
735 */
UI_Shutdown(void)736 void UI_Shutdown( void ) {
737 const uicmd_t *uicmd;
738
739 ui_background->changedFunc = NULL;
740
741 PlayerModel_Free();
742
743 for( uicmd = uicmds; uicmd->name; uicmd++ ) {
744 cmd.RemoveCommand( uicmd->name );
745 }
746 }
747
748 #ifndef UI_HARD_LINKED
749
750 // this is only here so the functions in q_shared.c can link
751
Com_Printf(const char * fmt,...)752 void Com_Printf( const char *fmt, ... ) {
753 va_list argptr;
754 char text[MAXPRINTMSG];
755
756 va_start( argptr, fmt );
757 Q_vsnprintf( text, sizeof( text ), fmt, argptr );
758 va_end( argptr );
759
760 com.Print( PRINT_ALL, text );
761 }
762
Com_DPrintf(const char * fmt,...)763 void Com_DPrintf( const char *fmt, ... ) {
764 va_list argptr;
765 char text[MAXPRINTMSG];
766
767 va_start( argptr, fmt );
768 Q_vsnprintf( text, sizeof( text ), fmt, argptr );
769 va_end( argptr );
770
771 com.Print( PRINT_DEVELOPER, text );
772 }
773
Com_WPrintf(const char * fmt,...)774 void Com_WPrintf( const char *fmt, ... ) {
775 va_list argptr;
776 char text[MAXPRINTMSG];
777
778 va_start( argptr, fmt );
779 Q_vsnprintf( text, sizeof( text ), fmt, argptr );
780 va_end( argptr );
781
782 com.Print( PRINT_WARNING, text );
783 }
784
Com_EPrintf(const char * fmt,...)785 void Com_EPrintf( const char *fmt, ... ) {
786 va_list argptr;
787 char text[MAXPRINTMSG];
788
789 va_start( argptr, fmt );
790 Q_vsnprintf( text, sizeof( text ), fmt, argptr );
791 va_end( argptr );
792
793 com.Print( PRINT_ERROR, text );
794 }
795
Com_Error(comErrorType_t type,const char * error,...)796 void Com_Error( comErrorType_t type, const char *error, ... ) {
797 va_list argptr;
798 char text[MAXPRINTMSG];
799
800 va_start( argptr, error );
801 Q_vsnprintf( text, sizeof( text ), error, argptr );
802 va_end( argptr );
803
804 com.Error( type, text );
805 }
806
807 #endif
808
809 /*
810 =================
811 UI_FillAPI
812 =================
813 */
UI_FillAPI(uiAPI_t * api)814 static void UI_FillAPI( uiAPI_t *api ) {
815 api->Init = UI_Init;
816 api->Shutdown = UI_Shutdown;
817 api->Draw = UI_Draw;
818 api->DrawLoading = UI_DrawLoading;
819 api->MouseMove = UI_MouseMove;
820 api->Keydown = UI_Keydown;
821 api->CharEvent = UI_CharEvent;
822 api->OpenMenu = UI_OpenMenu;
823 api->ErrorMenu = UI_ErrorMenu;
824 api->AddToServerList = UI_AddToServerList;
825 api->IsTransparent = UI_IsTransparent;
826 }
827
828 /*
829 =================
830 UI_APISetupCallback
831 =================
832 */
UI_APISetupCallback(api_type_t type,void * api)833 static qboolean UI_APISetupCallback( api_type_t type, void *api ) {
834 switch( type ) {
835 case API_UI:
836 UI_FillAPI( ( uiAPI_t * )api );
837 break;
838 default:
839 return qfalse;
840 }
841
842 return qtrue;
843 }
844
845 #ifndef UI_HARD_LINKED
846
847 /*
848 @@@@@@@@@@@@@@@@@@@@@
849 moduleEntry
850
851 @@@@@@@@@@@@@@@@@@@@@
852 */
moduleEntry(int query,void * data)853 void *moduleEntry( int query, void *data ) {
854 moduleInfo_t *info;
855 moduleCapability_t caps;
856 APISetupCallback_t callback;
857
858 switch( query ) {
859 case MQ_GETINFO:
860 info = ( moduleInfo_t * )data;
861 info->api_version = MODULES_APIVERSION;
862 Q_strncpyz( info->fullname, "User interface library",
863 sizeof( info->fullname ) );
864 Q_strncpyz( info->author, "Andrey Nazarov", sizeof( info->author ) );
865 return ( void * )qtrue;
866
867 case MQ_GETCAPS:
868 caps = MCP_UI;
869 return ( void * )caps;
870
871 case MQ_SETUPAPI:
872 if( ( callback = ( APISetupCallback_t )data ) == NULL ) {
873 return NULL;
874 }
875 callback( API_CMD, &cmd );
876 callback( API_CVAR, &cvar );
877 callback( API_FS, &fs );
878 callback( API_COMMON, &com );
879 callback( API_SYSTEM, &sys );
880 callback( API_REFRESH, &ref );
881 callback( API_KEYS, &keys );
882 callback( API_CLIENT, &client );
883
884 return ( void * )UI_APISetupCallback;
885
886 }
887
888 /* quiet compiler warning */
889 return NULL;
890 }
891
892 #endif
893
894
895
896
897
898
899
900