1947 lines
47 KiB
C
1947 lines
47 KiB
C
|
/*
|
||
|
===========================================================================
|
||
|
Copyright (C) 1999-2005 Id Software, Inc.
|
||
|
Copyright (C) 2007 HermitWorks Entertainment Corporation
|
||
|
|
||
|
This file is part of the Space Trader source code.
|
||
|
|
||
|
The Space Trader source code is free software; you can redistribute it
|
||
|
and/or modify it under the terms of the GNU General Public License as
|
||
|
published by the Free Software Foundation; either version 2 of the License,
|
||
|
or (at your option) any later version.
|
||
|
|
||
|
The Space Trader source code is distributed in the hope that it will be
|
||
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with the Space Trader source code; if not, write to the Free Software
|
||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
===========================================================================
|
||
|
*/
|
||
|
|
||
|
#include "ui_local.h"
|
||
|
|
||
|
/*
|
||
|
=======================================================================
|
||
|
|
||
|
USER INTERFACE MAIN
|
||
|
|
||
|
=======================================================================
|
||
|
*/
|
||
|
|
||
|
uiInfo_t uiInfo;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
static const char *MonthAbbrev[] = {
|
||
|
"Jan","Feb","Mar",
|
||
|
"Apr","May","Jun",
|
||
|
"Jul","Aug","Sep",
|
||
|
"Oct","Nov","Dec"
|
||
|
};
|
||
|
|
||
|
#define MAX_MENU_STACKS 64
|
||
|
|
||
|
menuStackDef_t ui_menuStack;
|
||
|
menuStackDef_t cg_menuStack;
|
||
|
|
||
|
|
||
|
static void UI_StartServerRefresh( void );
|
||
|
static void UI_StopServerRefresh( void );
|
||
|
static void UI_DoServerRefresh( void );
|
||
|
|
||
|
extern void Save_Item( fileHandle_t f, itemDef_t * item );
|
||
|
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
vmMain
|
||
|
|
||
|
This is the only way control passes into the module.
|
||
|
This must be the very first function compiled into the .qvm file
|
||
|
================
|
||
|
*/
|
||
|
vmCvar_t ui_new;
|
||
|
vmCvar_t ui_debug;
|
||
|
vmCvar_t ui_initialized;
|
||
|
vmCvar_t ui_spacetrader;
|
||
|
vmCvar_t ui_tooltipmode;
|
||
|
vmCvar_t ui_drawMenu;
|
||
|
|
||
|
void _UI_Init( qboolean );
|
||
|
void _UI_Shutdown( qboolean );
|
||
|
void _UI_KeyEvent( int key, qboolean down );
|
||
|
int _UI_MouseEvent( int dx, int dy );
|
||
|
void _UI_Refresh( int realtime );
|
||
|
qboolean _UI_IsFullscreen( void );
|
||
|
|
||
|
extern int debug_cgmenu;
|
||
|
extern int UI_GlobalInt();
|
||
|
|
||
|
int QDECL vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 )
|
||
|
{
|
||
|
REF_PARAM( arg3 );
|
||
|
REF_PARAM( arg4 );
|
||
|
REF_PARAM( arg5 );
|
||
|
REF_PARAM( arg6 );
|
||
|
REF_PARAM( arg7 );
|
||
|
REF_PARAM( arg8 );
|
||
|
REF_PARAM( arg9 );
|
||
|
REF_PARAM( arg10 );
|
||
|
REF_PARAM( arg11 );
|
||
|
|
||
|
if ( debug_cgmenu )
|
||
|
UI_SetMenuStack( &cg_menuStack );
|
||
|
else
|
||
|
UI_SetMenuStack( &ui_menuStack );
|
||
|
|
||
|
switch ( command ) {
|
||
|
case UI_GETAPIVERSION:
|
||
|
return UI_API_VERSION;
|
||
|
|
||
|
case UI_INIT:
|
||
|
_UI_Init(arg0);
|
||
|
uiInfo.clientNum = arg1;
|
||
|
return 0;
|
||
|
|
||
|
case UI_GAMEINIT:
|
||
|
{
|
||
|
UI_ST_exec( UI_ST_INIT_GAME );
|
||
|
} return 0;
|
||
|
|
||
|
case UI_SHUTDOWN:
|
||
|
_UI_Shutdown(arg0);
|
||
|
return 0;
|
||
|
|
||
|
case UI_KEY_EVENT:
|
||
|
_UI_KeyEvent( arg1, arg2 );
|
||
|
return 0;
|
||
|
|
||
|
case UI_MOUSE_EVENT:
|
||
|
return _UI_MouseEvent( arg1, arg2 );
|
||
|
|
||
|
case UI_REFRESH:
|
||
|
if ( (GS_INPLAY || !ui_spacetrader.integer) &&
|
||
|
!(trap_Key_GetCatcher() & KEYCATCH_UI) &&
|
||
|
!_UI_IsFullscreen() )
|
||
|
UI_SetMenuStack( &cg_menuStack );
|
||
|
|
||
|
_UI_Refresh( arg1 );
|
||
|
return 0;
|
||
|
|
||
|
case UI_IS_FULLSCREEN:
|
||
|
return _UI_IsFullscreen();
|
||
|
|
||
|
case UI_SET_ACTIVE_MENU:
|
||
|
_UI_SetActiveMenu( arg0 );
|
||
|
return 0;
|
||
|
|
||
|
case UI_CONSOLE_COMMAND:
|
||
|
return UI_ConsoleCommand(arg0);
|
||
|
|
||
|
case UI_DRAW_CONNECT_SCREEN:
|
||
|
UI_DrawConnectScreen( arg0 );
|
||
|
return 0;
|
||
|
case UI_REPORT_HIGHSCORE_RESPONSE:
|
||
|
UI_ST_exec(UI_ST_REPORT_HIGHSCORE_RESPONSE, arg0);
|
||
|
return 0;
|
||
|
case UI_AUTHORIZED:
|
||
|
UI_ST_exec(UI_ST_AUTHORIZED, arg0, arg1);
|
||
|
return 0;
|
||
|
case UI_SERVER_ERRORMESSAGE:
|
||
|
UI_ST_exec(UI_ST_SERVER_ERRORMESSAGE, arg0 );
|
||
|
return 0;
|
||
|
case UI_GLOBAL_INT:
|
||
|
return UI_GlobalInt();
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void AssetCache() {
|
||
|
int n;
|
||
|
|
||
|
for( n = 0; n < NUM_CROSSHAIRS; n++ ) {
|
||
|
uiInfo.uiDC.Assets.crosshairShader[n] = trap_R_RegisterShaderNoMip( va("gfx/2d/crosshair%c", 'a' + n ) );
|
||
|
}
|
||
|
//REMOVE SOUND
|
||
|
//uiInfo.newHighScoreSound = trap_S_RegisterSound("sound/feedback/voc_newhighscore.wav", qfalse);
|
||
|
|
||
|
uiInfo.uiDC.Assets.shipModel = trap_R_RegisterModel( ASSET_PLANETMODEL );
|
||
|
uiInfo.uiDC.Assets.planetModel = trap_R_RegisterModel( ASSET_PLANETMODEL );
|
||
|
|
||
|
uiInfo.uiDC.Assets.orbit = trap_R_RegisterShaderNoMip( "ui/assets/orbit" );
|
||
|
uiInfo.uiDC.Assets.orbitSel = trap_R_RegisterShaderNoMip( "ui/assets/orbitsel" );
|
||
|
|
||
|
uiInfo.uiDC.Assets.star = trap_R_RegisterShaderNoMip( "ui/assets/star" );
|
||
|
uiInfo.uiDC.Assets.menu = trap_R_RegisterShaderNoMip( "ui/assets/menubrushed" );
|
||
|
uiInfo.uiDC.Assets.menubar = trap_R_RegisterShaderNoMip( "ui/assets/menubar" );
|
||
|
uiInfo.uiDC.Assets.sbThumb = trap_R_RegisterShaderNoMip( "ui/assets/scrollarrows" );
|
||
|
uiInfo.uiDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip( "ui/assets/slider" );
|
||
|
uiInfo.uiDC.Assets.lineshadow = trap_R_RegisterShaderNoMip( "ui/assets/pricegraph_shadow" );
|
||
|
uiInfo.uiDC.Assets.redbar = trap_R_RegisterShaderNoMip( "ui/assets/redalpha" );
|
||
|
uiInfo.uiDC.Assets.radar_player = trap_R_RegisterShaderNoMip( "radarPlayer" );
|
||
|
uiInfo.uiDC.Assets.radar_bot = trap_R_RegisterShaderNoMip( "radarBot" );
|
||
|
|
||
|
}
|
||
|
|
||
|
void _UI_DrawSides(float x, float y, float w, float h, float size) {
|
||
|
UI_AdjustFrom640( &x, &y, &w, &h );
|
||
|
size *= uiInfo.uiDC.glconfig.xscale;
|
||
|
trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
|
||
|
trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
|
||
|
}
|
||
|
|
||
|
void _UI_DrawTopBottom(float x, float y, float w, float h, float size) {
|
||
|
UI_AdjustFrom640( &x, &y, &w, &h );
|
||
|
size *= uiInfo.uiDC.glconfig.yscale;
|
||
|
trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
|
||
|
trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
|
||
|
}
|
||
|
/*
|
||
|
================
|
||
|
UI_DrawRect
|
||
|
|
||
|
Coordinates are 640*480 virtual values
|
||
|
=================
|
||
|
*/
|
||
|
void _UI_DrawRect( float x, float y, float width, float height, float size, const float *color ) {
|
||
|
trap_R_SetColor( color );
|
||
|
|
||
|
_UI_DrawTopBottom(x, y, width, height, size);
|
||
|
_UI_DrawSides(x, y, width, height, size);
|
||
|
|
||
|
trap_R_SetColor( NULL );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=================
|
||
|
_UI_Refresh
|
||
|
=================
|
||
|
*/
|
||
|
|
||
|
void UI_DrawCenteredPic(qhandle_t image, int w, int h) {
|
||
|
int x, y;
|
||
|
x = (SCREEN_WIDTH - w) >> 1;
|
||
|
y = (SCREEN_HEIGHT - h) >> 1;
|
||
|
UI_DrawHandlePic((float)x, (float)y, (float)w, (float)h, image);
|
||
|
}
|
||
|
|
||
|
int frameCount = 0;
|
||
|
int startTime;
|
||
|
|
||
|
#define UI_FPS_FRAMES 4
|
||
|
void _UI_Refresh( int realtime )
|
||
|
{
|
||
|
static int index;
|
||
|
static int previousTimes[UI_FPS_FRAMES];
|
||
|
|
||
|
//if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) {
|
||
|
// return;
|
||
|
//}
|
||
|
|
||
|
uiInfo.uiDC.frameTime = realtime - uiInfo.uiDC.realTime;
|
||
|
uiInfo.uiDC.realTime = realtime;
|
||
|
|
||
|
previousTimes[index % UI_FPS_FRAMES] = uiInfo.uiDC.frameTime;
|
||
|
index++;
|
||
|
if ( index > UI_FPS_FRAMES ) {
|
||
|
int i, total;
|
||
|
// average multiple frames together to smooth changes out a bit
|
||
|
total = 0;
|
||
|
for ( i = 0 ; i < UI_FPS_FRAMES ; i++ ) {
|
||
|
total += previousTimes[i];
|
||
|
}
|
||
|
if ( !total ) {
|
||
|
total = 1;
|
||
|
}
|
||
|
uiInfo.uiDC.FPS = (float)(1000 * UI_FPS_FRAMES / total);
|
||
|
}
|
||
|
|
||
|
UI_ST_exec( UI_ST_REFRESH );
|
||
|
|
||
|
UI_UpdateCvars();
|
||
|
|
||
|
UI_Effects_Update();
|
||
|
|
||
|
if ( ui_drawMenu.integer ) {
|
||
|
if (Menu_Count() > 0) {
|
||
|
// paint all the menus
|
||
|
Menu_PaintAll();
|
||
|
// refresh server browser list
|
||
|
UI_DoServerRefresh();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
UI_Effects_Draw( 0 );
|
||
|
|
||
|
UI_ST_exec( UI_ST_PAINT );
|
||
|
|
||
|
// tool tips
|
||
|
if ( ui_tooltipmode.integer == 2 && UI_Effect_IsAlive( uiInfo.tooltip ) ) {
|
||
|
|
||
|
float xb = DC->glconfig.xbias / DC->glconfig.xscale;
|
||
|
rectDef_t r;
|
||
|
effectDef_t * e = UI_Effect_GetEffect( uiInfo.tooltip );
|
||
|
|
||
|
r.x = e->rect.x + (float)DC->cursorx;
|
||
|
r.y = e->rect.y + (float)DC->cursory;
|
||
|
r.w = e->rect.w;
|
||
|
r.h = e->rect.h;
|
||
|
|
||
|
// don't let rect go off screen
|
||
|
if ( r.x < -xb ) r.x = -xb;
|
||
|
if ( r.y < 0.0f ) r.y = 0.0f;
|
||
|
if ( r.x + r.w > 640.0f + xb ) r.x = 640.0f + xb - r.w;
|
||
|
if ( r.y + r.h > 480.0f ) r.y = 480.0f - r.h;
|
||
|
|
||
|
UI_Effect_SetJustRect( uiInfo.tooltip, &r );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=================
|
||
|
_UI_Shutdown
|
||
|
=================
|
||
|
*/
|
||
|
void _UI_Shutdown( qboolean save_menustack ) {
|
||
|
|
||
|
if ( save_menustack )
|
||
|
{
|
||
|
int i;
|
||
|
char info[ MAX_INFO_STRING ];
|
||
|
info[ 0 ] = '\0';
|
||
|
|
||
|
for ( i=0; i<ui_menuStack.count; i++ )
|
||
|
{
|
||
|
Q_strcat( info, sizeof(info), ui_menuStack.m[ i ]->window.name );
|
||
|
Q_strcat( info, sizeof(info), " " );
|
||
|
}
|
||
|
|
||
|
trap_Cvar_Set( "ui_menustack", info );
|
||
|
} else
|
||
|
trap_Cvar_Set( "ui_menustack", "" );
|
||
|
|
||
|
}
|
||
|
|
||
|
static int QDECL SortEffects( const void *arg1, const void *arg2 ) {
|
||
|
effectDef_t ** a = (effectDef_t**)arg1;
|
||
|
effectDef_t ** b = (effectDef_t**)arg2;
|
||
|
|
||
|
return Q_stricmp( (*a)->name, (*b)->name );
|
||
|
}
|
||
|
|
||
|
qboolean Asset_Parse(int handle) {
|
||
|
pc_token_t token;
|
||
|
const char *tempStr;
|
||
|
cachedAssets_t * a = &uiInfo.uiDC.Assets;
|
||
|
|
||
|
if (!trap_PC_ReadToken(handle, &token))
|
||
|
return qfalse;
|
||
|
if (Q_stricmp(token.string, "{") != 0) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
|
||
|
for( ; ; )
|
||
|
{
|
||
|
|
||
|
memset(&token, 0, sizeof(pc_token_t));
|
||
|
|
||
|
if (!trap_PC_ReadToken(handle, &token))
|
||
|
return qfalse;
|
||
|
|
||
|
if (Q_stricmp(token.string, "}") == 0) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
switch( SWITCHSTRING( token.string ) )
|
||
|
{
|
||
|
case CS('f','o','n','t'):
|
||
|
if (!PC_String_Parse(handle, &tempStr)) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
a->font = trap_R_RegisterFont(tempStr);
|
||
|
break;
|
||
|
|
||
|
case CS('m','e','n','u'):
|
||
|
{
|
||
|
switch( SWITCHSTRING( token.string + 4 ) )
|
||
|
{
|
||
|
// menuEnterSound
|
||
|
case CS('e','n','t','e'):
|
||
|
if (!PC_String_Parse(handle, &tempStr)) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
a->menuEnterSound = trap_S_RegisterSound( tempStr, qfalse );
|
||
|
break;
|
||
|
|
||
|
// menuExitSound
|
||
|
case CS('e','x','i','t'):
|
||
|
if (!PC_String_Parse(handle, &tempStr)) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
a->menuExitSound = trap_S_RegisterSound( tempStr, qfalse );
|
||
|
break;
|
||
|
// menuBuzzSound
|
||
|
case CS('b','u','z','z'):
|
||
|
if (!PC_String_Parse(handle, &tempStr)) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
a->menuBuzzSound = trap_S_RegisterSound( tempStr, qfalse );
|
||
|
break;
|
||
|
}
|
||
|
} break;
|
||
|
|
||
|
case CS('d','i','n','g'):
|
||
|
{
|
||
|
int i = token.string[ 4 ] - '0';
|
||
|
if ( i < 0 || i > 4 )
|
||
|
return qfalse;
|
||
|
|
||
|
if (!PC_String_Parse(handle, &tempStr)) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
a->dings[ i ] = trap_S_RegisterSound( tempStr, qfalse );
|
||
|
} break;
|
||
|
// itemFocusSound
|
||
|
case CS('i','t','e','m'):
|
||
|
if (!PC_String_Parse(handle, &tempStr)) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
a->itemFocusSound = trap_S_RegisterSound( tempStr, qfalse );
|
||
|
break;
|
||
|
|
||
|
// cursor
|
||
|
case CS('c','u','r','s'):
|
||
|
if (!PC_String_Parse(handle, &a->cursorStr)) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
a->cursor = trap_R_RegisterShaderNoMip( a->cursorStr);
|
||
|
break;
|
||
|
|
||
|
case CS('f','a','d','e'):
|
||
|
{
|
||
|
switch( SWITCHSTRING( token.string + 4 ) )
|
||
|
{
|
||
|
// fadeClamp
|
||
|
case CS('c','l','a','m'):
|
||
|
if (!PC_Float_Parse(handle, &a->fadeClamp)) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
break;
|
||
|
// fadeCycle
|
||
|
case CS('c','y','c','l'):
|
||
|
if (!PC_Int_Parse(handle, &a->fadeCycle)) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
break;
|
||
|
// fadeAmount
|
||
|
case CS('a','m','o','u'):
|
||
|
if (!PC_Float_Parse(handle, &a->fadeAmount)) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
} break;
|
||
|
// effectDef_t
|
||
|
case CS('e','f','f','e'):
|
||
|
{
|
||
|
|
||
|
if ( a->effectCount < lengthof(a->effects) )
|
||
|
{
|
||
|
effectDef_t * effect = UI_Alloc( sizeof(effectDef_t) );
|
||
|
a->effects[ a->effectCount++ ] = effect;
|
||
|
|
||
|
if ( !Effect_Parse( handle, effect ) )
|
||
|
return qfalse;
|
||
|
}
|
||
|
|
||
|
} break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
qsort( a->effects, a->effectCount, sizeof(a->effects[0]), SortEffects );
|
||
|
return qtrue;
|
||
|
}
|
||
|
|
||
|
void UI_ParseStrings( const char * stringFile ) {
|
||
|
|
||
|
int handle;
|
||
|
|
||
|
handle = trap_PC_LoadSource( stringFile );
|
||
|
if ( !handle ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
const char * id;
|
||
|
const char * src;
|
||
|
int index;
|
||
|
|
||
|
if ( !PC_String_Parse( handle, &id ) )
|
||
|
break;
|
||
|
|
||
|
if ( !PC_String_Parse( handle, &src ) )
|
||
|
break;
|
||
|
|
||
|
index = trap_SQL_Compile( src );
|
||
|
|
||
|
sql( "INSERT INTO strings(index,name) VALUES(?1,$2);", "ite", index,id );
|
||
|
}
|
||
|
|
||
|
trap_PC_FreeSource(handle);
|
||
|
}
|
||
|
|
||
|
void UI_ParseMenu(const char *menuFile) {
|
||
|
int handle;
|
||
|
pc_token_t token;
|
||
|
|
||
|
handle = trap_PC_LoadSource(menuFile);
|
||
|
if (!handle) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for( ; ; )
|
||
|
{
|
||
|
memset(&token, 0, sizeof(pc_token_t));
|
||
|
if (!trap_PC_ReadToken( handle, &token )) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//if ( Q_stricmp( token, "{" ) ) {
|
||
|
// Com_Printf( "Missing { in menu file\n" );
|
||
|
// break;
|
||
|
//}
|
||
|
|
||
|
//if ( menuCount == MAX_MENUS ) {
|
||
|
// Com_Printf( "Too many menus!\n" );
|
||
|
// break;
|
||
|
//}
|
||
|
|
||
|
if ( token.string[0] == '}' ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (Q_stricmp(token.string, "assetGlobalDef") == 0) {
|
||
|
if (Asset_Parse(handle)) {
|
||
|
continue;
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (Q_stricmp(token.string, "menudef") == 0) {
|
||
|
// start a new menu
|
||
|
Menu_New(handle, menuFile );
|
||
|
}
|
||
|
}
|
||
|
trap_PC_FreeSource(handle);
|
||
|
}
|
||
|
|
||
|
#ifdef DEVELOPER
|
||
|
int FindThing( const char * text, const char * tag, const char * markerBegin, const char * markerEnd, const char * thingname, const char ** begin, const char ** end )
|
||
|
{
|
||
|
const char * def = 0;
|
||
|
int braces=0;
|
||
|
int found;
|
||
|
int brace=0;
|
||
|
const char * a = 0;
|
||
|
const char * b = 0;
|
||
|
char * t = 0;
|
||
|
const char * last = 0;
|
||
|
|
||
|
for ( found=0; !(found && brace==braces); )
|
||
|
{
|
||
|
last = text;
|
||
|
t = COM_ParseExt( &text, qtrue );
|
||
|
|
||
|
if ( t[ 0 ] == '\0' )
|
||
|
break;
|
||
|
|
||
|
if ( !Q_stricmp( t, tag ) )
|
||
|
{
|
||
|
t = COM_ParseExt( &text, qtrue );
|
||
|
if ( t[ 0 ] != '{' )
|
||
|
return 0;
|
||
|
|
||
|
def = text;
|
||
|
brace = ++braces;
|
||
|
|
||
|
if ( !thingname ) // no name take first one
|
||
|
found = 1;
|
||
|
}
|
||
|
|
||
|
if ( t[ 0 ] == '{' )
|
||
|
braces++;
|
||
|
|
||
|
if ( t[ 0 ] == '}' )
|
||
|
braces--;
|
||
|
|
||
|
if ( braces == brace+1 && !Q_stricmp( t, "name" ) )
|
||
|
{
|
||
|
t = COM_ParseExt( &text, qtrue );
|
||
|
if ( !Q_stricmp( t, thingname ) )
|
||
|
found = 1;
|
||
|
}
|
||
|
|
||
|
if ( found && thingname && !Q_stricmp( t, "itemDef" ) )
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( found )
|
||
|
{
|
||
|
a = Q_strstr( def, text-def, markerBegin );
|
||
|
b = Q_strstr( def, text-def, markerEnd );
|
||
|
|
||
|
if ( a < def || a > text )
|
||
|
a = last;
|
||
|
|
||
|
if ( b >= def && b < text )
|
||
|
{
|
||
|
b += strlen( markerEnd );
|
||
|
|
||
|
} else
|
||
|
b = last;
|
||
|
|
||
|
*begin = a;
|
||
|
*end = b;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void writef( fileHandle_t f, const char * t ) {
|
||
|
trap_FS_Write( t, strlen(t), f );
|
||
|
}
|
||
|
|
||
|
static void writef_rect( fileHandle_t f, const char * name, rectDef_t * r ) {
|
||
|
writef( f, va("%s\t\t%d %d %d %d\n", name, (int)r->x, (int)r->y, (int)r->w, (int)r->h ) );
|
||
|
}
|
||
|
|
||
|
static void writef_int( fileHandle_t f, const char * name, int i ) {
|
||
|
writef( f, va("%s\t\t%d\n", name, i ) );
|
||
|
}
|
||
|
|
||
|
|
||
|
void Save_Menu( menuDef_t * menu, const char * filename )
|
||
|
{
|
||
|
char buffer[ 65535 * 4 ];
|
||
|
fileHandle_t f;
|
||
|
const char * start;
|
||
|
const char * end;
|
||
|
int i,len;
|
||
|
const char * search;
|
||
|
const char * menuMarkerBegin = "\n\t\t//--editor.menu.begin--\n";
|
||
|
const char * menuMarkerEnd = "\t\t//--editor.menu.end--\n";
|
||
|
const char * itemMarkerBegin = "\n\t\t\t//--editor.item.begin--\n";
|
||
|
const char * itemMarkerEnd = "\t\t\t//--editor.item.end--\n";
|
||
|
float x = uiInfo.uiDC.glconfig.xbias / uiInfo.uiDC.glconfig.xscale;
|
||
|
|
||
|
len = trap_FS_FOpenFile( filename, &f, FS_READ );
|
||
|
|
||
|
if ( !f ) {
|
||
|
trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) );
|
||
|
return;
|
||
|
}
|
||
|
if ( len >= sizeof(buffer) ) {
|
||
|
trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, sizeof(buffer) ) );
|
||
|
trap_FS_FCloseFile( f );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
trap_FS_Read( buffer, len, f );
|
||
|
buffer[len] = 0;
|
||
|
if ( !FindThing( buffer, "menuDef", menuMarkerBegin, menuMarkerEnd, menu->window.name, &start, &end ) )
|
||
|
return;
|
||
|
|
||
|
trap_FS_FCloseFile( f );
|
||
|
trap_FS_FOpenFile( filename, &f, FS_UPDATE );
|
||
|
|
||
|
// write everything previous to menu
|
||
|
trap_FS_Write( buffer, start-buffer, f );
|
||
|
|
||
|
// write menu
|
||
|
writef( f, menuMarkerBegin );
|
||
|
menu->window.rectClient = menu->window.rect;
|
||
|
|
||
|
if ( menu->window.flags & WINDOW_ALIGNLEFT ) {
|
||
|
menu->window.rectClient.x += x;
|
||
|
} else if ( menu->window.flags & WINDOW_ALIGNRIGHT ) {
|
||
|
menu->window.rectClient.x -= x;
|
||
|
} else if ( menu->window.flags & WINDOW_ALIGNWIDTH ) {
|
||
|
float right = (menu->window.rectClient.x + menu->window.rectClient.w) - x*2.0f;
|
||
|
menu->window.rectClient.x += x;
|
||
|
menu->window.rectClient.w = right - menu->window.rectClient.x;
|
||
|
}
|
||
|
|
||
|
writef_rect( f, "\t\trect", &menu->window.rectClient );
|
||
|
writef_int( f, "\t\tstyle", menu->window.style );
|
||
|
writef( f, menuMarkerEnd );
|
||
|
|
||
|
search = end;
|
||
|
// write items
|
||
|
for ( i=0; i<menu->itemCount; i++ )
|
||
|
{
|
||
|
const char * itemBegin;
|
||
|
const char * itemEnd;
|
||
|
itemDef_t * item = menu->items[ i ];
|
||
|
|
||
|
if ( !FindThing( search, "itemDef", itemMarkerBegin, itemMarkerEnd, 0, &itemBegin, &itemEnd ) )
|
||
|
{
|
||
|
trap_Print( va( S_COLOR_RED "couldn't finish saving menu file %s\n", filename ) );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// write everything before item
|
||
|
trap_FS_Write( search, itemBegin-search, f );
|
||
|
|
||
|
writef( f, itemMarkerBegin );
|
||
|
Save_Item( f, item );
|
||
|
writef( f, itemMarkerEnd );
|
||
|
|
||
|
search = itemEnd;
|
||
|
}
|
||
|
|
||
|
// write everything after menu
|
||
|
trap_FS_Write( search, len-(search-buffer), f );
|
||
|
|
||
|
trap_FS_FCloseFile( f );
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
qboolean Load_Menu(int handle) {
|
||
|
pc_token_t token;
|
||
|
|
||
|
if (!trap_PC_ReadToken(handle, &token))
|
||
|
return qfalse;
|
||
|
if (token.string[0] != '{') {
|
||
|
return qfalse;
|
||
|
}
|
||
|
|
||
|
for( ; ; )
|
||
|
{
|
||
|
|
||
|
if (!trap_PC_ReadToken(handle, &token))
|
||
|
return qfalse;
|
||
|
|
||
|
if ( token.string[0] == 0 ) {
|
||
|
return qfalse;
|
||
|
}
|
||
|
|
||
|
if ( token.string[0] == '}' ) {
|
||
|
return qtrue;
|
||
|
}
|
||
|
|
||
|
UI_ParseMenu(token.string);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void UI_LoadMenus(const char *menuFile, qboolean reset) {
|
||
|
pc_token_t token;
|
||
|
int handle;
|
||
|
int start;
|
||
|
|
||
|
start = trap_Milliseconds();
|
||
|
|
||
|
handle = trap_PC_LoadSource( menuFile );
|
||
|
if (!handle) {
|
||
|
trap_Error( ERR_DROP, va( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile ) );
|
||
|
handle = trap_PC_LoadSource( "ui/menus.txt" );
|
||
|
if (!handle) {
|
||
|
trap_Error( ERR_DROP, va( S_COLOR_RED "default menu file not found: ui/menus.txt, unable to continue!\n", menuFile ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ui_new.integer = 1;
|
||
|
|
||
|
if (reset) {
|
||
|
Menu_Reset();
|
||
|
}
|
||
|
|
||
|
for( ; ; )
|
||
|
{
|
||
|
if (!trap_PC_ReadToken(handle, &token))
|
||
|
break;
|
||
|
if( token.string[0] == 0 || token.string[0] == '}') {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( token.string[0] == '}' ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (Q_stricmp(token.string, "loadmenu") == 0) {
|
||
|
if (Load_Menu(handle)) {
|
||
|
continue;
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Com_Printf("UI menu load time = %d milli seconds\n", trap_Milliseconds() - start);
|
||
|
|
||
|
trap_PC_FreeSource( handle );
|
||
|
}
|
||
|
|
||
|
|
||
|
static void UI_DrawCrosshair( itemDef_t * item, vec4_t color )
|
||
|
{
|
||
|
rectDef_t * rect = &item->window.rect;
|
||
|
vec4_t hcolor;
|
||
|
|
||
|
REF_PARAM( color );
|
||
|
|
||
|
hcolor[0] = trap_Cvar_VariableValue("cg_crosshairColorR");
|
||
|
hcolor[1] = trap_Cvar_VariableValue("cg_crosshairColorG");
|
||
|
hcolor[2] = trap_Cvar_VariableValue("cg_crosshairColorB");
|
||
|
hcolor[3] = trap_Cvar_VariableValue("cg_crosshairColorA");
|
||
|
|
||
|
trap_R_SetColor( hcolor );
|
||
|
if (uiInfo.currentCrosshair < 0 || uiInfo.currentCrosshair >= NUM_CROSSHAIRS) {
|
||
|
uiInfo.currentCrosshair = 0;
|
||
|
}
|
||
|
UI_DrawHandlePic( rect->x + item->textdivx + 8.0f, rect->y, rect->h, rect->h, uiInfo.uiDC.Assets.crosshairShader[uiInfo.currentCrosshair]);
|
||
|
trap_R_SetColor( NULL );
|
||
|
}
|
||
|
|
||
|
|
||
|
const char* UI_GetOwnerText( int id )
|
||
|
{
|
||
|
if( id == 0 )
|
||
|
return "";
|
||
|
|
||
|
switch ( id )
|
||
|
{
|
||
|
case 0: return 0;
|
||
|
case BG_TOOLTIP:
|
||
|
{
|
||
|
int i;
|
||
|
for ( i=ui_menuStack.count-1; i>=0; i-- )
|
||
|
{
|
||
|
menuDef_t * menu = ui_menuStack.m[ i ];
|
||
|
if ( menu && menu->focusItem && menu->focusItem->tooltip ) {
|
||
|
if ( sql( "SELECT index FROM strings SEARCH name $;", "t", menu->focusItem->tooltip ) ) {
|
||
|
int tooltip = sqlint(0);
|
||
|
sqldone();
|
||
|
|
||
|
return UI_ST_getString( tooltip );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
} break;
|
||
|
case UI_KEYBINDSTATUS: return (Display_KeyBindPending())?"Waiting for new key... Press ESCAPE to cancel":"Press ENTER or CLICK to change, Press BACKSPACE to clear";
|
||
|
|
||
|
default:
|
||
|
return UI_ST_getString( id );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void UI_OwnerDraw( itemDef_t * item, vec4_t color )
|
||
|
{
|
||
|
switch( item->window.ownerDraw )
|
||
|
{
|
||
|
case UI_CROSSHAIR:
|
||
|
UI_DrawCrosshair( item, color);
|
||
|
break;
|
||
|
default:
|
||
|
UI_ST_exec( UI_ST_OWNERDRAW_PAINT, item );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
static qboolean UI_Crosshair_HandleKey( int flags, int key )
|
||
|
{
|
||
|
REF_PARAM( flags );
|
||
|
|
||
|
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
|
||
|
if (key == K_MOUSE2) {
|
||
|
uiInfo.currentCrosshair--;
|
||
|
} else {
|
||
|
uiInfo.currentCrosshair++;
|
||
|
}
|
||
|
|
||
|
if (uiInfo.currentCrosshair >= NUM_CROSSHAIRS) {
|
||
|
uiInfo.currentCrosshair = 0;
|
||
|
} else if (uiInfo.currentCrosshair < 0) {
|
||
|
uiInfo.currentCrosshair = NUM_CROSSHAIRS - 1;
|
||
|
}
|
||
|
trap_Cvar_Set("cg_drawCrosshair", va("%d", uiInfo.currentCrosshair));
|
||
|
return qtrue;
|
||
|
}
|
||
|
return qfalse;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
UNREFERENCED LOCAL FUNCTION
|
||
|
|
||
|
static qboolean UI_NumericRange_HandleKey( int* val, float *special, int key,
|
||
|
int min, int max, int bigAmt )
|
||
|
{
|
||
|
if( key & K_CHAR_FLAG )
|
||
|
{
|
||
|
key &= ~K_CHAR_FLAG;
|
||
|
|
||
|
if( key < '0' || key > '9' )
|
||
|
return qfalse;
|
||
|
|
||
|
if( *special == 0 )
|
||
|
{
|
||
|
*val = key - '0';
|
||
|
*special = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*val = atoi( va( "%i%c", *val, key ) );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
switch( key )
|
||
|
{
|
||
|
case K_BACKSPACE:
|
||
|
if( *special != 0 )
|
||
|
{
|
||
|
char *s = va( "%i", *val );
|
||
|
int l = strlen( s );
|
||
|
|
||
|
if( l )
|
||
|
{
|
||
|
s[l - 1] = '\0';
|
||
|
|
||
|
if( l == 1 )
|
||
|
*special = 0;
|
||
|
}
|
||
|
|
||
|
*val = atoi( s );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case K_MWHEELUP:
|
||
|
case K_UPARROW:
|
||
|
(*val)++;
|
||
|
*special = 0;
|
||
|
break;
|
||
|
|
||
|
case K_MWHEELDOWN:
|
||
|
case K_DOWNARROW:
|
||
|
(*val)--;
|
||
|
*special = 0;
|
||
|
break;
|
||
|
|
||
|
case K_RIGHTARROW:
|
||
|
*val += bigAmt;
|
||
|
*special = 0;
|
||
|
break;
|
||
|
|
||
|
case K_LEFTARROW:
|
||
|
*val -= bigAmt;
|
||
|
*special = 0;
|
||
|
break;
|
||
|
|
||
|
case K_HOME:
|
||
|
*val = min;
|
||
|
*special = 0;
|
||
|
break;
|
||
|
|
||
|
case K_END:
|
||
|
*val = max;
|
||
|
*special = 0;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
return qfalse;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return qtrue;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
static qboolean UI_OwnerDrawHandleKey(int ownerDraw, int flags, int key)
|
||
|
{
|
||
|
switch (ownerDraw)
|
||
|
{
|
||
|
case UI_CROSSHAIR:
|
||
|
UI_Crosshair_HandleKey(flags, key);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return qfalse;
|
||
|
}
|
||
|
|
||
|
static qboolean UI_OwnerDrawHandleMouseMove( itemDef_t * item, float x, float y )
|
||
|
{
|
||
|
switch( item->window.ownerDraw )
|
||
|
{
|
||
|
default:
|
||
|
UI_ST_exec( UI_ST_OWNERDRAW_MOUSEMOVE, item, x,y );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return qfalse;
|
||
|
}
|
||
|
|
||
|
static bool Validate_Name( const char *s )
|
||
|
{
|
||
|
if( !Info_Validate( s ) )
|
||
|
return false;
|
||
|
|
||
|
for( ; *s; s++ )
|
||
|
{
|
||
|
switch( *s )
|
||
|
{
|
||
|
case '\\':
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static void UI_Login() {
|
||
|
|
||
|
int logged_in = trap_Cvar_VariableInt( "ui_logged_in" );
|
||
|
|
||
|
if ( logged_in != -2 && logged_in != 1 ) {
|
||
|
|
||
|
char username[MAX_NAME_LENGTH];
|
||
|
char password[MAX_NAME_LENGTH];
|
||
|
|
||
|
trap_Cvar_VariableStringBuffer("ui_username", username, MAX_NAME_LENGTH);
|
||
|
trap_Cvar_VariableStringBuffer("ui_password", password, MAX_NAME_LENGTH);
|
||
|
|
||
|
if ( username[0] == '\0' || password[ 0 ] == '\0' )
|
||
|
{
|
||
|
trap_Cvar_Set( "ui_logged_in", "0" );
|
||
|
} else
|
||
|
{
|
||
|
trap_Cvar_Set( "ui_logged_in", "-2" );
|
||
|
trap_Cmd_ExecuteText( EXEC_APPEND, va("login \"%s\" \"%s\";\n", username, password) );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void UI_Update( const char *name )
|
||
|
{
|
||
|
int val = (int)trap_Cvar_VariableValue( name );
|
||
|
|
||
|
if ( name[ 0 ] == 'u' &&
|
||
|
name[ 1 ] == 'i' &&
|
||
|
name[ 2 ] == '_' )
|
||
|
{
|
||
|
switch( SWITCHSTRING( name+3 ) )
|
||
|
{
|
||
|
// ui_sethost
|
||
|
case CS('s','e','t','h'):
|
||
|
{
|
||
|
if (Info_Validate( UI_Cvar_VariableString( "ui_hostname" ) ) ) {
|
||
|
trap_Cvar_Set( "sv_hostname", UI_Cvar_VariableString( "ui_hostname" ) );
|
||
|
}
|
||
|
} break;
|
||
|
|
||
|
// ui_gethost
|
||
|
case CS('g','e','t','h'):
|
||
|
{
|
||
|
trap_Cvar_Set( "ui_hostname", UI_Cvar_VariableString("sv_hostname"));
|
||
|
} break;
|
||
|
|
||
|
// ui_SetName
|
||
|
case CS('S','e','t','N'):
|
||
|
{
|
||
|
if( Validate_Name( UI_Cvar_VariableString( "ui_Name" ) ) )
|
||
|
{
|
||
|
trap_Cvar_Set( "name", UI_Cvar_VariableString( "ui_Name" ) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//keep name and ui_name in sync
|
||
|
trap_Cvar_Set( "ui_Name", UI_Cvar_VariableString( "name" ) );
|
||
|
}
|
||
|
} break;
|
||
|
|
||
|
// ui_setRate
|
||
|
case CS('s','e','t','r'):
|
||
|
{
|
||
|
float rate = trap_Cvar_VariableValue( "rate" );
|
||
|
if( rate >= 5000 )
|
||
|
{
|
||
|
trap_Cvar_Set( "cl_maxpackets", "30" );
|
||
|
trap_Cvar_Set( "cl_packetdup", "1" );
|
||
|
}
|
||
|
else if( rate >= 4000 )
|
||
|
{
|
||
|
trap_Cvar_Set( "cl_maxpackets", "15" );
|
||
|
trap_Cvar_Set( "cl_packetdup", "2" ); // favor less prediction errors when there's packet loss
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
trap_Cvar_Set( "cl_maxpackets", "15" );
|
||
|
trap_Cvar_Set( "cl_packetdup", "1" ); // favor lower bandwidth
|
||
|
}
|
||
|
} break;
|
||
|
|
||
|
// ui_GetName
|
||
|
case CS('g','e','t','n'):
|
||
|
{
|
||
|
trap_Cvar_Set( "ui_Name", UI_Cvar_VariableString("name"));
|
||
|
} break;
|
||
|
|
||
|
// ui_glCustom
|
||
|
case CS('g','l','c','u'):
|
||
|
{
|
||
|
switch( val )
|
||
|
{
|
||
|
case 0: // high quality
|
||
|
trap_Cvar_SetValue( "r_fullScreen", 1 );
|
||
|
trap_Cvar_SetValue( "r_subdivisions", 4 );
|
||
|
trap_Cvar_SetValue( "r_vertexlight", 0 );
|
||
|
trap_Cvar_SetValue( "r_lodbias", 0 );
|
||
|
trap_Cvar_SetValue( "r_colorbits", 32 );
|
||
|
trap_Cvar_SetValue( "r_depthbits", 24 );
|
||
|
trap_Cvar_SetValue( "r_picmip", 0 );
|
||
|
trap_Cvar_SetValue( "r_mode", 5 );
|
||
|
trap_Cvar_SetValue( "r_fastSky", 0 );
|
||
|
trap_Cvar_SetValue( "r_inGameVideo", 1 );
|
||
|
trap_Cvar_SetValue( "cg_shadows", 1 );
|
||
|
trap_Cvar_SetValue( "cg_brassTime", 2500 );
|
||
|
trap_Cvar_Set( "r_texturemode", "LinearMipLinear" );
|
||
|
break;
|
||
|
case 1: // normal
|
||
|
trap_Cvar_SetValue( "r_fullScreen", 1 );
|
||
|
trap_Cvar_SetValue( "r_subdivisions", 12 );
|
||
|
trap_Cvar_SetValue( "r_vertexlight", 0 );
|
||
|
trap_Cvar_SetValue( "r_lodbias", 0 );
|
||
|
trap_Cvar_SetValue( "r_colorbits", 0 );
|
||
|
trap_Cvar_SetValue( "r_depthbits", 24 );
|
||
|
trap_Cvar_SetValue( "r_picmip", 1 );
|
||
|
trap_Cvar_SetValue( "r_mode", 4 );
|
||
|
trap_Cvar_SetValue( "r_fastSky", 0 );
|
||
|
trap_Cvar_SetValue( "r_inGameVideo", 1 );
|
||
|
trap_Cvar_SetValue( "cg_brassTime", 2500 );
|
||
|
trap_Cvar_Set( "r_texturemode", "LinearMipLinear" );
|
||
|
trap_Cvar_SetValue( "cg_shadows", 0 );
|
||
|
break;
|
||
|
case 2: // fast
|
||
|
trap_Cvar_SetValue( "r_fullScreen", 1 );
|
||
|
trap_Cvar_SetValue( "r_subdivisions", 8 );
|
||
|
trap_Cvar_SetValue( "r_vertexlight", 0 );
|
||
|
trap_Cvar_SetValue( "r_lodbias", 1 );
|
||
|
trap_Cvar_SetValue( "r_colorbits", 0 );
|
||
|
trap_Cvar_SetValue( "r_depthbits", 0 );
|
||
|
trap_Cvar_SetValue( "r_picmip", 1 );
|
||
|
trap_Cvar_SetValue( "r_mode", 3 );
|
||
|
trap_Cvar_SetValue( "cg_shadows", 0 );
|
||
|
trap_Cvar_SetValue( "r_fastSky", 1 );
|
||
|
trap_Cvar_SetValue( "r_inGameVideo", 0 );
|
||
|
trap_Cvar_SetValue( "cg_brassTime", 0 );
|
||
|
trap_Cvar_Set( "r_texturemode", "LinearMipLinear" );
|
||
|
trap_Cvar_Set( "r_fsaa", "0");
|
||
|
break;
|
||
|
case 3: // fastest
|
||
|
trap_Cvar_SetValue( "r_fullScreen", 1 );
|
||
|
trap_Cvar_SetValue( "r_subdivisions", 20 );
|
||
|
trap_Cvar_SetValue( "r_vertexlight", 1 );
|
||
|
trap_Cvar_SetValue( "r_lodbias", 2 );
|
||
|
trap_Cvar_SetValue( "r_colorbits", 16 );
|
||
|
trap_Cvar_SetValue( "r_depthbits", 16 );
|
||
|
trap_Cvar_SetValue( "r_mode", 3 );
|
||
|
trap_Cvar_SetValue( "r_picmip", 2 );
|
||
|
trap_Cvar_SetValue( "cg_shadows", 0 );
|
||
|
trap_Cvar_SetValue( "cg_brassTime", 0 );
|
||
|
trap_Cvar_SetValue( "r_fastSky", 1 );
|
||
|
trap_Cvar_SetValue( "r_inGameVideo", 0 );
|
||
|
trap_Cvar_Set( "r_texturemode", "LinearMipNearest" );
|
||
|
trap_Cvar_Set( "r_fsaa", "0");
|
||
|
break;
|
||
|
}
|
||
|
} break;
|
||
|
|
||
|
// ui_mousePitch
|
||
|
case CS('m','o','u','s'):
|
||
|
{
|
||
|
trap_Cvar_SetValue( "m_pitch", val ? -0.022F : 0.022F );
|
||
|
} break;
|
||
|
}
|
||
|
|
||
|
} else if ( name[ 0 ] == 'r' &&
|
||
|
name[ 1 ] == '_' )
|
||
|
{
|
||
|
switch( SWITCHSTRING( name+2 ) )
|
||
|
{
|
||
|
// r_colorbits
|
||
|
case CS('c','o','l','o'):
|
||
|
{
|
||
|
switch( val )
|
||
|
{
|
||
|
case 0:
|
||
|
trap_Cvar_SetValue( "r_depthbits", 0 );
|
||
|
trap_Cvar_SetValue( "r_stencilbits", 0 );
|
||
|
break;
|
||
|
|
||
|
case 16:
|
||
|
trap_Cvar_SetValue( "r_depthbits", 16 );
|
||
|
trap_Cvar_SetValue( "r_stencilbits", 0 );
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
trap_Cvar_SetValue( "r_depthbits", 24 );
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
} break;
|
||
|
// r_lodbias
|
||
|
case CS('l','o','d','b'):
|
||
|
{
|
||
|
switch( val )
|
||
|
{
|
||
|
case 0:
|
||
|
trap_Cvar_SetValue( "r_subdivisions", 4 );
|
||
|
break;
|
||
|
case 1:
|
||
|
trap_Cvar_SetValue( "r_subdivisions", 12 );
|
||
|
break;
|
||
|
case 2:
|
||
|
trap_Cvar_SetValue( "r_subdivisions", 20 );
|
||
|
break;
|
||
|
}
|
||
|
} break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void UI_RunMenuScript( const char **args )
|
||
|
{
|
||
|
const char *name, *name2;
|
||
|
|
||
|
if( String_Parse( args, &name ) )
|
||
|
{
|
||
|
if ( name[ 0 ] == 's' && name[ 1 ] == 't' && name[ 2 ] == '_' )
|
||
|
{
|
||
|
// menu script commands prefixed with 'st_' are destined for rules engine...
|
||
|
UI_ST_exec( UI_ST_SCRIPTCOMMAND, name+3, args );
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
else if( Q_stricmp( name, "resetDefaults" ) == 0 )
|
||
|
{
|
||
|
trap_Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n");
|
||
|
trap_Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n");
|
||
|
Controls_SetDefaults();
|
||
|
trap_Cvar_Set("com_introPlayed", "1" );
|
||
|
trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" );
|
||
|
}
|
||
|
else if( Q_stricmp( name, "saveControls" ) == 0 )
|
||
|
{
|
||
|
Controls_SetConfig(qtrue);
|
||
|
}
|
||
|
else if( Q_stricmp( name, "loadControls" ) == 0 )
|
||
|
{
|
||
|
Controls_GetConfig();
|
||
|
}
|
||
|
else if( Q_stricmp( name, "clearError" ) == 0 )
|
||
|
{
|
||
|
trap_Cvar_Set("com_errorMessage", "");
|
||
|
}
|
||
|
else if( Q_stricmp( name, "RefreshServers" ) == 0 )
|
||
|
{
|
||
|
UI_StartServerRefresh();
|
||
|
}
|
||
|
else if( Q_stricmp( name, "RefreshFilter" ) == 0 )
|
||
|
{
|
||
|
UI_StartServerRefresh();
|
||
|
}
|
||
|
else if( Q_stricmp( name, "StopRefresh" ) == 0 )
|
||
|
{
|
||
|
UI_StopServerRefresh();
|
||
|
}
|
||
|
else if( Q_stricmp( name, "UpdateFilter" ) == 0 )
|
||
|
{
|
||
|
if (ui_netSource.integer == AS_LOCAL) {
|
||
|
UI_StartServerRefresh();
|
||
|
}
|
||
|
}
|
||
|
else if( Q_stricmp( name, "JoinServer" ) == 0 )
|
||
|
{
|
||
|
if ( sql( "SELECT addr FROM servers WHERE #=feeders.name[ 'serverlist' ].id;", 0 ) ) {
|
||
|
|
||
|
trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", sqltext(0) ) );
|
||
|
sqldone();
|
||
|
}
|
||
|
}
|
||
|
else if( Q_stricmp( name, "Quit" ) == 0 )
|
||
|
{
|
||
|
trap_Cmd_ExecuteText( EXEC_NOW, "quit" );
|
||
|
}
|
||
|
else if( Q_stricmp( name, "Leave" ) == 0 )
|
||
|
{
|
||
|
if ( trap_Cvar_VariableInt("sv_running") == 0) {
|
||
|
trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" );
|
||
|
} else {
|
||
|
trap_Cmd_ExecuteText( EXEC_APPEND, "killserver\n");
|
||
|
|
||
|
}
|
||
|
Menus_CloseAll();
|
||
|
}
|
||
|
else if( Q_stricmp( name, "glCustom" ) == 0 )
|
||
|
{
|
||
|
trap_Cvar_Set( "ui_glCustom", "4" );
|
||
|
}
|
||
|
else if( Q_stricmp( name, "update" ) == 0 )
|
||
|
{
|
||
|
if( String_Parse( args, &name2 ) )
|
||
|
UI_Update( name2 );
|
||
|
}
|
||
|
else if( Q_stricmp( name, "setPbClStatus" ) == 0 )
|
||
|
{
|
||
|
int stat;
|
||
|
if ( Int_Parse( args, &stat ) )
|
||
|
trap_SetPbClStatus( stat );
|
||
|
}
|
||
|
else if ( Q_stricmp( name, "gethighscores") == 0 )
|
||
|
{
|
||
|
UI_ST_exec( UI_ST_REQUEST_HIGHSCORES );
|
||
|
}
|
||
|
else if( Q_stricmp( name, "login" ) == 0 )
|
||
|
{
|
||
|
UI_Login();
|
||
|
}
|
||
|
else if( Q_stricmp( name, "closebugreport" ) == 0 )
|
||
|
{
|
||
|
trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_BUG );
|
||
|
}
|
||
|
else if ( Q_stricmp( name, "registergame" ) == 0 )
|
||
|
{
|
||
|
trap_Cmd_ExecuteText( EXEC_APPEND, va("register %s\n", UI_Cvar_VariableString( "ui_licensekey" ) ) );
|
||
|
}
|
||
|
else if ( Q_stricmp( name, "checkupdates" ) == 0 )
|
||
|
{
|
||
|
trap_Cvar_Set( "com_changelog", "Space Trader is up to date." );
|
||
|
trap_Cvar_Set( "com_downloadbar_x", COM_Parse( args ) );
|
||
|
trap_Cvar_Set( "com_downloadbar_y", COM_Parse( args ) );
|
||
|
trap_Cvar_Set( "com_downloadbar_w", COM_Parse( args ) );
|
||
|
trap_Cvar_Set( "com_downloadbar_h", COM_Parse( args ) );
|
||
|
trap_Cmd_ExecuteText( EXEC_APPEND, "check_updates" );
|
||
|
}
|
||
|
#ifdef DEVELOPER
|
||
|
else if ( Q_stricmp( name, "editorupdate" ) == 0 )
|
||
|
{
|
||
|
UI_Editor_UpdateItem();
|
||
|
}
|
||
|
#endif
|
||
|
else
|
||
|
{
|
||
|
Com_Printf( "unknown UI script %s\n", name );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
qboolean UI_hasSkinForBase(const char *base, const char *team) {
|
||
|
char test[1024];
|
||
|
|
||
|
Com_sprintf( test, sizeof( test ), "models/players/%s/%s/lower_default.skin", base, team );
|
||
|
|
||
|
if (trap_FS_FOpenFile(test, 0, FS_READ)) {
|
||
|
return qtrue;
|
||
|
}
|
||
|
Com_sprintf( test, sizeof( test ), "models/players/characters/%s/%s/lower_default.skin", base, team );
|
||
|
|
||
|
if (trap_FS_FOpenFile(test, 0, FS_READ)) {
|
||
|
return qtrue;
|
||
|
}
|
||
|
return qfalse;
|
||
|
}
|
||
|
|
||
|
static int UI_PlayCinematic(const char *name, float x, float y, float w, float h) {
|
||
|
return trap_CIN_PlayCinematic( name, (int)x, (int)y, (int)w, (int)h, (CIN_loop | CIN_silent) );
|
||
|
}
|
||
|
|
||
|
static void UI_StopCinematic(int handle) {
|
||
|
if ( handle >= 0 )
|
||
|
{
|
||
|
trap_CIN_StopCinematic(handle);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void UI_DrawCinematic( int handle, float x, float y, float w, float h )
|
||
|
{
|
||
|
trap_CIN_SetExtents( handle, (int)x, (int)y, (int)w, (int)h );
|
||
|
trap_CIN_DrawCinematic(handle);
|
||
|
}
|
||
|
|
||
|
static void UI_RunCinematicFrame( int handle )
|
||
|
{
|
||
|
trap_CIN_RunCinematic( handle );
|
||
|
}
|
||
|
|
||
|
|
||
|
void UI_Cvar_Set( const char* cvar, const char* value )
|
||
|
{
|
||
|
trap_Cvar_Set( cvar, value );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=================
|
||
|
UI_Init
|
||
|
=================
|
||
|
*/
|
||
|
void _UI_Init( qboolean inGameLoad ) {
|
||
|
int start;
|
||
|
|
||
|
//uiInfo.inGameLoad = inGameLoad;
|
||
|
|
||
|
UI_RegisterCvars();
|
||
|
UI_InitMemory();
|
||
|
UI_Effect_Init();
|
||
|
|
||
|
// cache redundant calulations
|
||
|
trap_GetGlconfig( &uiInfo.uiDC.glconfig );
|
||
|
|
||
|
|
||
|
//UI_Load();
|
||
|
uiInfo.uiDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip;
|
||
|
uiInfo.uiDC.setColor = &trap_R_SetColor;
|
||
|
uiInfo.uiDC.drawHandlePic = &UI_DrawHandlePic;
|
||
|
uiInfo.uiDC.drawStretchPic = &trap_R_DrawStretchPic;
|
||
|
uiInfo.uiDC.registerModel = &trap_R_RegisterModel;
|
||
|
uiInfo.uiDC.modelBounds = &trap_R_ModelBounds;
|
||
|
uiInfo.uiDC.fillRect = &trap_R_RenderRoundRect;
|
||
|
uiInfo.uiDC.drawRect = &_UI_DrawRect;
|
||
|
uiInfo.uiDC.drawSides = &_UI_DrawSides;
|
||
|
uiInfo.uiDC.drawTopBottom = &_UI_DrawTopBottom;
|
||
|
uiInfo.uiDC.clearScene = &trap_R_ClearScene;
|
||
|
uiInfo.uiDC.drawSides = &_UI_DrawSides;
|
||
|
uiInfo.uiDC.addRefEntityToScene = &trap_R_AddRefEntityToScene;
|
||
|
uiInfo.uiDC.renderScene = &trap_R_RenderScene;
|
||
|
uiInfo.uiDC.registerFont = &trap_R_RegisterFont;
|
||
|
uiInfo.uiDC.ownerDrawItem = &UI_OwnerDraw;
|
||
|
uiInfo.uiDC.runScript = &UI_RunMenuScript;
|
||
|
uiInfo.uiDC.setCVar = UI_Cvar_Set;
|
||
|
uiInfo.uiDC.getCVarString = trap_Cvar_VariableStringBuffer;
|
||
|
uiInfo.uiDC.getCVarValue = trap_Cvar_VariableValue;
|
||
|
uiInfo.uiDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode;
|
||
|
uiInfo.uiDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode;
|
||
|
uiInfo.uiDC.startLocalSound = &trap_S_StartLocalSound;
|
||
|
uiInfo.uiDC.ownerDrawHandleKey = &UI_OwnerDrawHandleKey;
|
||
|
uiInfo.uiDC.ownerDrawHandleMouseMove = &UI_OwnerDrawHandleMouseMove;
|
||
|
uiInfo.uiDC.setBinding = &trap_Key_SetBinding;
|
||
|
uiInfo.uiDC.getBindingBuf = &trap_Key_GetBindingBuf;
|
||
|
uiInfo.uiDC.keynumToStringBuf = &trap_Key_KeynumToStringBuf;
|
||
|
uiInfo.uiDC.executeText = &trap_Cmd_ExecuteText;
|
||
|
uiInfo.uiDC.Error = &Com_Error;
|
||
|
uiInfo.uiDC.Print = &Com_Printf;
|
||
|
uiInfo.uiDC.registerSound = &trap_S_RegisterSound;
|
||
|
uiInfo.uiDC.startBackgroundTrack = &trap_S_StartBackgroundTrack;
|
||
|
uiInfo.uiDC.stopBackgroundTrack = &trap_S_StopBackgroundTrack;
|
||
|
uiInfo.uiDC.playCinematic = &UI_PlayCinematic;
|
||
|
uiInfo.uiDC.stopCinematic = &UI_StopCinematic;
|
||
|
uiInfo.uiDC.drawCinematic = &UI_DrawCinematic;
|
||
|
uiInfo.uiDC.runCinematicFrame = &UI_RunCinematicFrame;
|
||
|
uiInfo.uiDC.getOwnerText = &UI_GetOwnerText;
|
||
|
uiInfo.uiDC.getClientNum = &trap_GetClientNum;
|
||
|
uiInfo.uiDC.toolTip = &UI_Effects_UpdateToolTip;
|
||
|
|
||
|
Init_Display(&uiInfo.uiDC);
|
||
|
|
||
|
memset( &ui_menuStack, 0, sizeof(ui_menuStack) );
|
||
|
String_Init();
|
||
|
|
||
|
uiInfo.uiDC.whiteShader = trap_R_RegisterShaderNoMip( "*white" );
|
||
|
|
||
|
AssetCache();
|
||
|
|
||
|
start = trap_Milliseconds();
|
||
|
|
||
|
uiInfo.traveltime = 0;
|
||
|
uiInfo.maxplayers = 8;
|
||
|
|
||
|
{
|
||
|
char tmp[ MAX_INFO_STRING ];
|
||
|
trap_GetConfigString( CS_SERVERINFO, tmp, sizeof(tmp) );
|
||
|
uiInfo.maxplayers = atoi( Info_ValueForKey( tmp, "sv_maxplayers" ) );
|
||
|
}
|
||
|
|
||
|
trap_SQL_Exec(
|
||
|
"CREATE TABLE feeders"
|
||
|
"("
|
||
|
"name STRING, "
|
||
|
"sel INTEGER, "
|
||
|
"id INTEGER, "
|
||
|
"enabled INTEGER "
|
||
|
");"
|
||
|
|
||
|
"CREATE TABLE sliders"
|
||
|
"("
|
||
|
"name STRING, "
|
||
|
"value INTEGER "
|
||
|
");"
|
||
|
|
||
|
"CREATE TABLE IF NOT EXISTS strings"
|
||
|
"("
|
||
|
"index INTEGER, "
|
||
|
"name STRING "
|
||
|
");"
|
||
|
|
||
|
"CREATE TABLE ui"
|
||
|
"("
|
||
|
"key STRING, "
|
||
|
"value INTEGER "
|
||
|
");"
|
||
|
|
||
|
);
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef USE_DRM
|
||
|
trap_PC_AddGlobalDefine( "USE_DRM" );
|
||
|
#endif
|
||
|
#ifdef DEMO
|
||
|
trap_PC_AddGlobalDefine( "DEMO" );
|
||
|
#endif
|
||
|
|
||
|
// check to see if 'cl_lang' is valid, default to english.
|
||
|
if ( sql( "SELECT 1 FROM common.files SEARCH fullname 'ui/strings_'||$1||'.txt';", "t", UI_Cvar_VariableString("cl_lang") ) ) {
|
||
|
sqldone();
|
||
|
} else {
|
||
|
UI_Cvar_Set( "cl_lang", "en-US" );
|
||
|
}
|
||
|
|
||
|
trap_PC_AddGlobalDefine( va("LANG \"%s\"",UI_Cvar_VariableString("cl_lang")) );
|
||
|
|
||
|
{
|
||
|
char tmp[ 64 ];
|
||
|
trap_SQL_Run( tmp, sizeof(tmp), 0, 0,0,0 );
|
||
|
if ( tmp[ 0 ] == '\0' ) {
|
||
|
trap_SQL_Compile( "1" );
|
||
|
UI_ParseStrings( va("ui/strings_%s.txt",UI_Cvar_VariableString("cl_lang")) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( inGameLoad )
|
||
|
UI_LoadMenus( "ui/ingame.txt", qtrue );
|
||
|
else
|
||
|
UI_LoadMenus( "ui/menus.txt", qtrue);
|
||
|
|
||
|
uiInfo.tooltipDef1 = UI_Effect_Find( "tooltip1" );
|
||
|
uiInfo.tooltipDef2 = UI_Effect_Find( "tooltip2" );
|
||
|
|
||
|
#ifdef DEVELOPER
|
||
|
UI_Editor_Init();
|
||
|
#endif
|
||
|
|
||
|
Menus_CloseAll();
|
||
|
|
||
|
// initialize rules engine
|
||
|
if ( !inGameLoad )
|
||
|
UI_ST_exec( UI_ST_INIT_FRONTEND );
|
||
|
|
||
|
UI_LoadBots();
|
||
|
|
||
|
// sets defaults for ui temp cvars
|
||
|
uiInfo.currentCrosshair = (int)trap_Cvar_VariableValue("cg_drawCrosshair");
|
||
|
trap_Cvar_Set("ui_mousePitch", (trap_Cvar_VariableValue("m_pitch") >= 0) ? "0" : "1");
|
||
|
|
||
|
uiInfo.serverStatus.currentServerCinematic = -1;
|
||
|
|
||
|
trap_Cvar_Register(NULL, "debug_protocol", "", 0 );
|
||
|
|
||
|
uiInfo.missionStatus = 0; // the mission is in progress
|
||
|
sql( "SELECT index FROM strings SEARCH name $;", "tsId", "T_Yes", &uiInfo.T_Yes );
|
||
|
sql( "SELECT index FROM strings SEARCH name $;", "tsId", "T_No", &uiInfo.T_No );
|
||
|
|
||
|
trap_Key_SetCatcher( 0 );
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
=================
|
||
|
UI_KeyEvent
|
||
|
=================
|
||
|
*/
|
||
|
void _UI_KeyEvent( int key, qboolean down )
|
||
|
{
|
||
|
Display_HandleKey( key, down, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory );
|
||
|
|
||
|
if ( !Menu_GetFocused() )
|
||
|
{
|
||
|
trap_Key_ClearStates();
|
||
|
trap_Cvar_Set( "cl_paused", "0" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
=================
|
||
|
UI_MouseEvent
|
||
|
=================
|
||
|
*/
|
||
|
int _UI_MouseEvent( int dx, int dy )
|
||
|
{
|
||
|
UI_AdjustTo640( &dx, &dy );
|
||
|
|
||
|
// update mouse screen position
|
||
|
uiInfo.uiDC.cursorx = dx;
|
||
|
uiInfo.uiDC.cursory = dy;
|
||
|
|
||
|
return Display_MouseMove( uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory );
|
||
|
}
|
||
|
|
||
|
void _UI_SetActiveMenu( uiMenuCommand_t menu )
|
||
|
{
|
||
|
char buf[256];
|
||
|
|
||
|
// this should be the ONLY way the menu system is brought up
|
||
|
// enusure minumum menu data is cached
|
||
|
if( Menu_Count() > 0 )
|
||
|
{
|
||
|
vec3_t v;
|
||
|
v[0] = v[1] = v[2] = 0;
|
||
|
switch( menu )
|
||
|
{
|
||
|
case UIMENU_NONE:
|
||
|
trap_Key_ClearStates();
|
||
|
trap_Cvar_Set( "cl_paused", "0" );
|
||
|
Menus_CloseAll();
|
||
|
|
||
|
return;
|
||
|
|
||
|
case UIMENU_MAIN:
|
||
|
|
||
|
UI_SetMenuStack( &cg_menuStack );
|
||
|
Menus_CloseAll();
|
||
|
UI_SetMenuStack( &ui_menuStack );
|
||
|
Menus_CloseAll();
|
||
|
|
||
|
if ( !GS_INPLAY && trap_Cvar_VariableInt( "com_downloading" ) == 1 ) {
|
||
|
Menus_ActivateByName( "downloading" );
|
||
|
} else {
|
||
|
|
||
|
Menus_ActivateByName( "welcome" );
|
||
|
|
||
|
UI_ST_exec( UI_ST_MAINMENU );
|
||
|
}
|
||
|
|
||
|
trap_Cvar_VariableStringBuffer( "com_errorMessage", buf, sizeof( buf ) );
|
||
|
if( strlen( buf ) )
|
||
|
{
|
||
|
if( Q_stricmp( "Disconnected from server", buf ) == 0 )
|
||
|
{
|
||
|
trap_Cvar_Set( "com_errorMessage", "" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
trap_Cvar_Set( "ui_errorMessage", buf );
|
||
|
Menus_ActivateByName( "error_popmenu" );
|
||
|
}
|
||
|
}
|
||
|
return;
|
||
|
|
||
|
case UIMENU_TEAM:
|
||
|
Menus_ActivateByName("team");
|
||
|
return;
|
||
|
|
||
|
case UIMENU_NEED_CD:
|
||
|
Menus_ActivateByName( "header" );
|
||
|
Menus_ActivateByName( "registergame" );
|
||
|
return;
|
||
|
|
||
|
case UIMENU_BAD_CD_KEY:
|
||
|
return;
|
||
|
|
||
|
case UIMENU_INGAME:
|
||
|
UI_ST_exec( UI_ST_INGAMEMENU );
|
||
|
return;
|
||
|
|
||
|
case UIMENU_CHAT:
|
||
|
UI_ST_exec( UI_ST_CHATMENU );
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
qboolean _UI_IsFullscreen( void ) {
|
||
|
return Menus_AnyFullScreenVisible();
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
========================
|
||
|
UI_DrawConnectScreen
|
||
|
|
||
|
This will also be overlaid on the cgame info screen during loading
|
||
|
to prevent it from blinking away too rapidly on local or lan games.
|
||
|
========================
|
||
|
*/
|
||
|
void UI_DrawConnectScreen( qboolean overlay )
|
||
|
{
|
||
|
char text[ MAX_INFO_STRING ];
|
||
|
uiClientState_t cstate;
|
||
|
rectDef_t r;
|
||
|
|
||
|
REF_PARAM( overlay );
|
||
|
|
||
|
//
|
||
|
// see what information we should display
|
||
|
//
|
||
|
trap_GetClientState( &cstate );
|
||
|
text[0] = '\0';
|
||
|
|
||
|
if (!Q_stricmp(cstate.servername,"localhost"))
|
||
|
{
|
||
|
Q_strcat( text, sizeof(text), "Loading...\n" );
|
||
|
|
||
|
} else {
|
||
|
Q_strcat( text, sizeof(text), va("Connecting to %s\n", cstate.servername));
|
||
|
|
||
|
switch ( cstate.connState )
|
||
|
{
|
||
|
case CA_CONNECTING: Q_strcat( text, sizeof(text), va("Awaiting connection...%i\n", cstate.connectPacketCount) ); break;
|
||
|
case CA_CHALLENGING: Q_strcat( text, sizeof(text), va("Awaiting challenge...%i\n", cstate.connectPacketCount) ); break;
|
||
|
case CA_CONNECTED: Q_strcat( text, sizeof(text), "Awaiting gamestate...\n" ); break;
|
||
|
case CA_UNINITIALIZED:
|
||
|
case CA_DISCONNECTED:
|
||
|
case CA_AUTHORIZING:
|
||
|
case CA_LOADING:
|
||
|
case CA_PRIMED:
|
||
|
case CA_ACTIVE:
|
||
|
case CA_CINEMATIC:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
r.x = 50.0f;
|
||
|
r.y = 0.0f;
|
||
|
r.w = 540.0f;
|
||
|
r.h = 450.0f;
|
||
|
trap_R_RenderText ( &r,
|
||
|
0.35f,
|
||
|
colorWhite,
|
||
|
text,
|
||
|
sizeof(text),
|
||
|
TEXT_ALIGN_RIGHT,
|
||
|
TEXT_ALIGN_RIGHT,
|
||
|
ITEM_TEXTSTYLE_SHADOWED | ITEM_TEXTSTYLE_ITALIC,
|
||
|
uiInfo.uiDC.Assets.font,
|
||
|
-1,
|
||
|
0
|
||
|
);
|
||
|
|
||
|
// password required / connection rejected information goes here
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
cvars
|
||
|
================
|
||
|
*/
|
||
|
|
||
|
typedef struct {
|
||
|
vmCvar_t *vmCvar;
|
||
|
char *cvarName;
|
||
|
char *defaultString;
|
||
|
int cvarFlags;
|
||
|
} cvarTable_t;
|
||
|
|
||
|
vmCvar_t ui_botsFile;
|
||
|
|
||
|
vmCvar_t ui_brassTime;
|
||
|
vmCvar_t ui_drawCrosshair;
|
||
|
vmCvar_t ui_drawCrosshairNames;
|
||
|
vmCvar_t ui_marks;
|
||
|
|
||
|
vmCvar_t ui_gameType;
|
||
|
vmCvar_t ui_netSource;
|
||
|
vmCvar_t ui_serverFilterType;
|
||
|
vmCvar_t ui_currentMap;
|
||
|
vmCvar_t ui_currentNetMap;
|
||
|
vmCvar_t ui_singlePlayerActive;
|
||
|
vmCvar_t ui_username;
|
||
|
vmCvar_t ui_password;
|
||
|
vmCvar_t ui_crosshairColorR;
|
||
|
vmCvar_t ui_crosshairColorG;
|
||
|
vmCvar_t ui_crosshairColorB;
|
||
|
vmCvar_t ui_crosshairColorA;
|
||
|
|
||
|
vmCvar_t cl_cornersize;
|
||
|
|
||
|
// bk001129 - made static to avoid aliasing
|
||
|
static cvarTable_t cvarTable[] = {
|
||
|
{ &ui_botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM },
|
||
|
|
||
|
{ &ui_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE },
|
||
|
{ &ui_drawCrosshair, "cg_drawCrosshair", "2", CVAR_ARCHIVE },
|
||
|
{ &ui_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE },
|
||
|
{ &ui_marks, "cg_marks", "1", CVAR_ARCHIVE },
|
||
|
|
||
|
{ &ui_new, "ui_new", "0", CVAR_TEMP },
|
||
|
{ &ui_debug, "ui_debug", "0", CVAR_TEMP },
|
||
|
{ &ui_initialized, "ui_initialized", "0", CVAR_TEMP },
|
||
|
{ &ui_spacetrader, "cl_spacetrader", "0", CVAR_TEMP },
|
||
|
{ &ui_netSource, "ui_netSource", "0", CVAR_ARCHIVE },
|
||
|
{ &ui_currentMap, "ui_currentMap", "0", CVAR_ARCHIVE },
|
||
|
{ &ui_currentNetMap, "ui_currentNetMap", "0", CVAR_ARCHIVE },
|
||
|
{ &ui_singlePlayerActive, "ui_singlePlayerActive", "0", 0},
|
||
|
{ &ui_tooltipmode, "ui_tooltipmode", "0", CVAR_ARCHIVE},
|
||
|
{ &ui_drawMenu, "ui_drawMenu", "1", CVAR_TEMP },
|
||
|
{ &ui_username, "ui_username", "", CVAR_ARCHIVE},
|
||
|
{ &ui_password, "ui_password", "", CVAR_ARCHIVE},
|
||
|
{ &ui_crosshairColorR, "cg_crosshairColorR", "1.0", CVAR_ARCHIVE},
|
||
|
{ &ui_crosshairColorG, "cg_crosshairColorG", "1.0", CVAR_ARCHIVE},
|
||
|
{ &ui_crosshairColorB, "cg_crosshairColorB", "1.0", CVAR_ARCHIVE},
|
||
|
{ &ui_crosshairColorA, "cg_crosshairColorA", "1.0", CVAR_ARCHIVE},
|
||
|
{ &cl_cornersize, "cl_cornersize", "", 0},
|
||
|
};
|
||
|
|
||
|
// bk001129 - made static to avoid aliasing
|
||
|
static int cvarTableSize = sizeof(cvarTable) / sizeof(cvarTable[0]);
|
||
|
|
||
|
|
||
|
/*
|
||
|
=================
|
||
|
UI_RegisterCvars
|
||
|
=================
|
||
|
*/
|
||
|
void UI_RegisterCvars( void ) {
|
||
|
int i;
|
||
|
cvarTable_t *cv;
|
||
|
|
||
|
for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
|
||
|
trap_Cvar_Register( cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=================
|
||
|
UI_UpdateCvars
|
||
|
=================
|
||
|
*/
|
||
|
void UI_UpdateCvars( void ) {
|
||
|
int i;
|
||
|
cvarTable_t *cv;
|
||
|
|
||
|
for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
|
||
|
trap_Cvar_Update( cv->vmCvar );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
=================
|
||
|
ArenaServers_StopRefresh
|
||
|
=================
|
||
|
*/
|
||
|
static void UI_StopServerRefresh( void )
|
||
|
{
|
||
|
if (!uiInfo.serverStatus.refreshActive) {
|
||
|
// not currently refreshing
|
||
|
return;
|
||
|
}
|
||
|
uiInfo.serverStatus.refreshActive = qfalse;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=================
|
||
|
UI_DoServerRefresh
|
||
|
=================
|
||
|
*/
|
||
|
static void UI_DoServerRefresh( void )
|
||
|
{
|
||
|
if (!uiInfo.serverStatus.refreshActive) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (uiInfo.uiDC.realTime > uiInfo.serverStatus.nextDisplayRefresh ) {
|
||
|
UI_StartServerRefresh();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (uiInfo.uiDC.realTime < uiInfo.serverStatus.refreshtime) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// if still trying to retrieve pings
|
||
|
if (trap_LAN_UpdateVisiblePings(ui_netSource.integer)) {
|
||
|
uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=================
|
||
|
UI_StartServerRefresh
|
||
|
=================
|
||
|
*/
|
||
|
static void UI_StartServerRefresh()
|
||
|
{
|
||
|
qtime_t q;
|
||
|
int delay;
|
||
|
trap_RealTime(&q);
|
||
|
trap_Cvar_Set( va("ui_lastServerRefresh_%i", ui_netSource.integer), va("%s-%i, %i at %i:%i", MonthAbbrev[q.tm_mon],q.tm_mday, 1900+q.tm_year,q.tm_hour,q.tm_min));
|
||
|
|
||
|
//
|
||
|
if( ui_netSource.integer == AS_LOCAL ) {
|
||
|
// clear number of displayed servers
|
||
|
sql( "DELETE FROM servers WHERE lastupdate < ?1;", "ie", uiInfo.uiDC.realTime-2000 );
|
||
|
trap_Cmd_ExecuteText( EXEC_NOW, "localservers\n" );
|
||
|
uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
|
||
|
delay = 2500;
|
||
|
} else {
|
||
|
// clear number of displayed servers
|
||
|
//sql( "DELETE FROM servers WHERE lastupdate < ?1;", "ie", uiInfo.uiDC.realTime-10000 );
|
||
|
|
||
|
uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 5000;
|
||
|
if( ui_netSource.integer == AS_GLOBAL ) {
|
||
|
trap_Cmd_ExecuteText( EXEC_NOW, "getservers" );
|
||
|
}
|
||
|
delay = 10000;
|
||
|
}
|
||
|
uiInfo.serverStatus.refreshActive = qtrue;
|
||
|
uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + delay;
|
||
|
}
|
||
|
|
||
|
void UI_Effects_UpdateToolTip( itemDef_t * item )
|
||
|
{
|
||
|
item;
|
||
|
#if 0
|
||
|
effectDef_t * e;
|
||
|
|
||
|
// kill old tooltip
|
||
|
if ( uiInfo.tooltip )
|
||
|
UI_Effect_SetFlag( uiInfo.tooltip, EF_NOFOCUS );
|
||
|
|
||
|
if ( ui_tooltipmode.integer == 0 )
|
||
|
return;
|
||
|
|
||
|
e = (ui_tooltipmode.integer==2)?uiInfo.tooltipDef2:uiInfo.tooltipDef1;
|
||
|
|
||
|
if ( item && item->tooltip && e )
|
||
|
{
|
||
|
char t[ EFFECT_TEXT_LENGTH ];
|
||
|
rectDef_t r;
|
||
|
r.x = e->rect.x + (float)uiInfo.uiDC.cursorx;
|
||
|
r.y = e->rect.x + (float)uiInfo.uiDC.cursory;
|
||
|
r.w = e->rect.w;
|
||
|
r.h = e->rect.h;
|
||
|
|
||
|
trap_SQL_Run( t, sizeof(t), item->tooltip, 0,0,0 );
|
||
|
uiInfo.tooltip = UI_Effect_SpawnText( 0, e, t, 0 );
|
||
|
UI_Effect_SetRect( uiInfo.tooltip, &r, item );
|
||
|
}
|
||
|
#endif
|
||
|
}
|