From 6bf20c78f5b69d40bcc4931df93d29198435ab67 Mon Sep 17 00:00:00 2001 From: zakk Date: Fri, 26 Aug 2005 17:39:27 +0000 Subject: newlines fixed git-svn-id: svn://svn.icculus.org/quake3/trunk@6 edf5b092-35ff-0310-97b2-ce42778d08ea --- code/q3_ui/ui_startserver.c | 3936 +++++++++++++++++++++---------------------- 1 file changed, 1968 insertions(+), 1968 deletions(-) (limited to 'code/q3_ui/ui_startserver.c') diff --git a/code/q3_ui/ui_startserver.c b/code/q3_ui/ui_startserver.c index 5bc3680..401f687 100755 --- a/code/q3_ui/ui_startserver.c +++ b/code/q3_ui/ui_startserver.c @@ -1,1968 +1,1968 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena 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. - -Quake III Arena 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 Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -============================================================================= - -START SERVER MENU ***** - -============================================================================= -*/ - - -#include "ui_local.h" - - -#define GAMESERVER_BACK0 "menu/art/back_0" -#define GAMESERVER_BACK1 "menu/art/back_1" -#define GAMESERVER_NEXT0 "menu/art/next_0" -#define GAMESERVER_NEXT1 "menu/art/next_1" -#define GAMESERVER_FRAMEL "menu/art/frame2_l" -#define GAMESERVER_FRAMER "menu/art/frame1_r" -#define GAMESERVER_SELECT "menu/art/maps_select" -#define GAMESERVER_SELECTED "menu/art/maps_selected" -#define GAMESERVER_FIGHT0 "menu/art/fight_0" -#define GAMESERVER_FIGHT1 "menu/art/fight_1" -#define GAMESERVER_UNKNOWNMAP "menu/art/unknownmap" -#define GAMESERVER_ARROWS "menu/art/gs_arrows_0" -#define GAMESERVER_ARROWSL "menu/art/gs_arrows_l" -#define GAMESERVER_ARROWSR "menu/art/gs_arrows_r" - -#define MAX_MAPROWS 2 -#define MAX_MAPCOLS 2 -#define MAX_MAPSPERPAGE 4 - -#define MAX_SERVERSTEXT 8192 - -#define MAX_SERVERMAPS 64 -#define MAX_NAMELENGTH 16 - -#define ID_GAMETYPE 10 -#define ID_PICTURES 11 // 12, 13, 14 -#define ID_PREVPAGE 15 -#define ID_NEXTPAGE 16 -#define ID_STARTSERVERBACK 17 -#define ID_STARTSERVERNEXT 18 - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - - menulist_s gametype; - menubitmap_s mappics[MAX_MAPSPERPAGE]; - menubitmap_s mapbuttons[MAX_MAPSPERPAGE]; - menubitmap_s arrows; - menubitmap_s prevpage; - menubitmap_s nextpage; - menubitmap_s back; - menubitmap_s next; - - menutext_s mapname; - menubitmap_s item_null; - - qboolean multiplayer; - int currentmap; - int nummaps; - int page; - int maxpages; - char maplist[MAX_SERVERMAPS][MAX_NAMELENGTH]; - int mapGamebits[MAX_SERVERMAPS]; -} startserver_t; - -static startserver_t s_startserver; - -static const char *gametype_items[] = { - "Free For All", - "Team Deathmatch", - "Tournament", - "Capture the Flag", - 0 -}; - -static int gametype_remap[] = {GT_FFA, GT_TEAM, GT_TOURNAMENT, GT_CTF}; -static int gametype_remap2[] = {0, 2, 0, 1, 3}; - -// use ui_servers2.c definition -extern const char* punkbuster_items[]; - -static void UI_ServerOptionsMenu( qboolean multiplayer ); - - -/* -================= -GametypeBits -================= -*/ -static int GametypeBits( char *string ) { - int bits; - char *p; - char *token; - - bits = 0; - p = string; - while( 1 ) { - token = COM_ParseExt( &p, qfalse ); - if( token[0] == 0 ) { - break; - } - - if( Q_stricmp( token, "ffa" ) == 0 ) { - bits |= 1 << GT_FFA; - continue; - } - - if( Q_stricmp( token, "tourney" ) == 0 ) { - bits |= 1 << GT_TOURNAMENT; - continue; - } - - if( Q_stricmp( token, "single" ) == 0 ) { - bits |= 1 << GT_SINGLE_PLAYER; - continue; - } - - if( Q_stricmp( token, "team" ) == 0 ) { - bits |= 1 << GT_TEAM; - continue; - } - - if( Q_stricmp( token, "ctf" ) == 0 ) { - bits |= 1 << GT_CTF; - continue; - } - } - - return bits; -} - - -/* -================= -StartServer_Update -================= -*/ -static void StartServer_Update( void ) { - int i; - int top; - static char picname[MAX_MAPSPERPAGE][64]; - - top = s_startserver.page*MAX_MAPSPERPAGE; - - for (i=0; i= s_startserver.nummaps) - break; - - Com_sprintf( picname[i], sizeof(picname[i]), "levelshots/%s", s_startserver.maplist[top+i] ); - - s_startserver.mappics[i].generic.flags &= ~QMF_HIGHLIGHT; - s_startserver.mappics[i].generic.name = picname[i]; - s_startserver.mappics[i].shader = 0; - - // reset - s_startserver.mapbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; - s_startserver.mapbuttons[i].generic.flags &= ~QMF_INACTIVE; - } - - for (; i=0 && i < MAX_MAPSPERPAGE ) - { - s_startserver.mappics[i].generic.flags |= QMF_HIGHLIGHT; - s_startserver.mapbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; - } - - // set the map name - strcpy( s_startserver.mapname.string, s_startserver.maplist[s_startserver.currentmap] ); - } - - Q_strupr( s_startserver.mapname.string ); -} - - -/* -================= -StartServer_MapEvent -================= -*/ -static void StartServer_MapEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED) { - return; - } - - s_startserver.currentmap = (s_startserver.page*MAX_MAPSPERPAGE) + (((menucommon_s*)ptr)->id - ID_PICTURES); - StartServer_Update(); -} - - -/* -================= -StartServer_GametypeEvent -================= -*/ -static void StartServer_GametypeEvent( void* ptr, int event ) { - int i; - int count; - int gamebits; - int matchbits; - const char *info; - - if( event != QM_ACTIVATED) { - return; - } - - count = UI_GetNumArenas(); - s_startserver.nummaps = 0; - matchbits = 1 << gametype_remap[s_startserver.gametype.curvalue]; - if( gametype_remap[s_startserver.gametype.curvalue] == GT_FFA ) { - matchbits |= ( 1 << GT_SINGLE_PLAYER ); - } - for( i = 0; i < count; i++ ) { - info = UI_GetArenaInfoByNumber( i ); - - gamebits = GametypeBits( Info_ValueForKey( info, "type") ); - if( !( gamebits & matchbits ) ) { - continue; - } - - Q_strncpyz( s_startserver.maplist[s_startserver.nummaps], Info_ValueForKey( info, "map"), MAX_NAMELENGTH ); - Q_strupr( s_startserver.maplist[s_startserver.nummaps] ); - s_startserver.mapGamebits[s_startserver.nummaps] = gamebits; - s_startserver.nummaps++; - } - s_startserver.maxpages = (s_startserver.nummaps + MAX_MAPSPERPAGE-1)/MAX_MAPSPERPAGE; - s_startserver.page = 0; - s_startserver.currentmap = 0; - - StartServer_Update(); -} - - -/* -================= -StartServer_MenuEvent -================= -*/ -static void StartServer_MenuEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_PREVPAGE: - if( s_startserver.page > 0 ) { - s_startserver.page--; - StartServer_Update(); - } - break; - - case ID_NEXTPAGE: - if( s_startserver.page < s_startserver.maxpages - 1 ) { - s_startserver.page++; - StartServer_Update(); - } - break; - - case ID_STARTSERVERNEXT: - trap_Cvar_SetValue( "g_gameType", gametype_remap[s_startserver.gametype.curvalue] ); - UI_ServerOptionsMenu( s_startserver.multiplayer ); - break; - - case ID_STARTSERVERBACK: - UI_PopMenu(); - break; - } -} - - -/* -=============== -StartServer_LevelshotDraw -=============== -*/ -static void StartServer_LevelshotDraw( void *self ) { - menubitmap_s *b; - int x; - int y; - int w; - int h; - int n; - - b = (menubitmap_s *)self; - - if( !b->generic.name ) { - return; - } - - if( b->generic.name && !b->shader ) { - b->shader = trap_R_RegisterShaderNoMip( b->generic.name ); - if( !b->shader && b->errorpic ) { - b->shader = trap_R_RegisterShaderNoMip( b->errorpic ); - } - } - - if( b->focuspic && !b->focusshader ) { - b->focusshader = trap_R_RegisterShaderNoMip( b->focuspic ); - } - - x = b->generic.x; - y = b->generic.y; - w = b->width; - h = b->height; - if( b->shader ) { - UI_DrawHandlePic( x, y, w, h, b->shader ); - } - - x = b->generic.x; - y = b->generic.y + b->height; - UI_FillRect( x, y, b->width, 28, colorBlack ); - - x += b->width / 2; - y += 4; - n = s_startserver.page * MAX_MAPSPERPAGE + b->generic.id - ID_PICTURES; - UI_DrawString( x, y, s_startserver.maplist[n], UI_CENTER|UI_SMALLFONT, color_orange ); - - x = b->generic.x; - y = b->generic.y; - w = b->width; - h = b->height + 28; - if( b->generic.flags & QMF_HIGHLIGHT ) { - UI_DrawHandlePic( x, y, w, h, b->focusshader ); - } -} - - -/* -================= -StartServer_MenuInit -================= -*/ -static void StartServer_MenuInit( void ) { - int i; - int x; - int y; - static char mapnamebuffer[64]; - - // zero set all our globals - memset( &s_startserver, 0 ,sizeof(startserver_t) ); - - StartServer_Cache(); - - s_startserver.menu.wrapAround = qtrue; - s_startserver.menu.fullscreen = qtrue; - - s_startserver.banner.generic.type = MTYPE_BTEXT; - s_startserver.banner.generic.x = 320; - s_startserver.banner.generic.y = 16; - s_startserver.banner.string = "GAME SERVER"; - s_startserver.banner.color = color_white; - s_startserver.banner.style = UI_CENTER; - - s_startserver.framel.generic.type = MTYPE_BITMAP; - s_startserver.framel.generic.name = GAMESERVER_FRAMEL; - s_startserver.framel.generic.flags = QMF_INACTIVE; - s_startserver.framel.generic.x = 0; - s_startserver.framel.generic.y = 78; - s_startserver.framel.width = 256; - s_startserver.framel.height = 329; - - s_startserver.framer.generic.type = MTYPE_BITMAP; - s_startserver.framer.generic.name = GAMESERVER_FRAMER; - s_startserver.framer.generic.flags = QMF_INACTIVE; - s_startserver.framer.generic.x = 376; - s_startserver.framer.generic.y = 76; - s_startserver.framer.width = 256; - s_startserver.framer.height = 334; - - s_startserver.gametype.generic.type = MTYPE_SPINCONTROL; - s_startserver.gametype.generic.name = "Game Type:"; - s_startserver.gametype.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_startserver.gametype.generic.callback = StartServer_GametypeEvent; - s_startserver.gametype.generic.id = ID_GAMETYPE; - s_startserver.gametype.generic.x = 320 - 24; - s_startserver.gametype.generic.y = 368; - s_startserver.gametype.itemnames = gametype_items; - - for (i=0; i= GT_TEAM) && - (s_serveroptions.playerTeam[n].curvalue != s_serveroptions.playerTeam[s_serveroptions.newBotIndex].curvalue ) ) { - continue; - } - if( Q_stricmp( checkName, s_serveroptions.playerNameBuffers[n] ) == 0 ) { - return qtrue; - } - } - - return qfalse; -} - - -/* -================= -ServerOptions_Start -================= -*/ -static void ServerOptions_Start( void ) { - int timelimit; - int fraglimit; - int maxclients; - int dedicated; - int friendlyfire; - int flaglimit; - int pure; - int skill; - int n; - char buf[64]; - - - timelimit = atoi( s_serveroptions.timelimit.field.buffer ); - fraglimit = atoi( s_serveroptions.fraglimit.field.buffer ); - flaglimit = atoi( s_serveroptions.flaglimit.field.buffer ); - dedicated = s_serveroptions.dedicated.curvalue; - friendlyfire = s_serveroptions.friendlyfire.curvalue; - pure = s_serveroptions.pure.curvalue; - skill = s_serveroptions.botSkill.curvalue + 1; - - //set maxclients - for( n = 0, maxclients = 0; n < PLAYER_SLOTS; n++ ) { - if( s_serveroptions.playerType[n].curvalue == 2 ) { - continue; - } - if( (s_serveroptions.playerType[n].curvalue == 1) && (s_serveroptions.playerNameBuffers[n][0] == 0) ) { - continue; - } - maxclients++; - } - - switch( s_serveroptions.gametype ) { - case GT_FFA: - default: - trap_Cvar_SetValue( "ui_ffa_fraglimit", fraglimit ); - trap_Cvar_SetValue( "ui_ffa_timelimit", timelimit ); - break; - - case GT_TOURNAMENT: - trap_Cvar_SetValue( "ui_tourney_fraglimit", fraglimit ); - trap_Cvar_SetValue( "ui_tourney_timelimit", timelimit ); - break; - - case GT_TEAM: - trap_Cvar_SetValue( "ui_team_fraglimit", fraglimit ); - trap_Cvar_SetValue( "ui_team_timelimit", timelimit ); - trap_Cvar_SetValue( "ui_team_friendlt", friendlyfire ); - break; - - case GT_CTF: - trap_Cvar_SetValue( "ui_ctf_fraglimit", fraglimit ); - trap_Cvar_SetValue( "ui_ctf_timelimit", timelimit ); - trap_Cvar_SetValue( "ui_ctf_friendlt", friendlyfire ); - break; - } - - trap_Cvar_SetValue( "sv_maxclients", Com_Clamp( 0, 12, maxclients ) ); - trap_Cvar_SetValue( "dedicated", Com_Clamp( 0, 2, dedicated ) ); - trap_Cvar_SetValue ("timelimit", Com_Clamp( 0, timelimit, timelimit ) ); - trap_Cvar_SetValue ("fraglimit", Com_Clamp( 0, fraglimit, fraglimit ) ); - trap_Cvar_SetValue ("capturelimit", Com_Clamp( 0, flaglimit, flaglimit ) ); - trap_Cvar_SetValue( "g_friendlyfire", friendlyfire ); - trap_Cvar_SetValue( "sv_pure", pure ); - trap_Cvar_Set("sv_hostname", s_serveroptions.hostname.field.buffer ); - - trap_Cvar_SetValue( "sv_punkbuster", s_serveroptions.punkbuster.curvalue ); - - // the wait commands will allow the dedicated to take effect - trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", s_startserver.maplist[s_startserver.currentmap] ) ); - - // add bots - trap_Cmd_ExecuteText( EXEC_APPEND, "wait 3\n" ); - for( n = 1; n < PLAYER_SLOTS; n++ ) { - if( s_serveroptions.playerType[n].curvalue != 1 ) { - continue; - } - if( s_serveroptions.playerNameBuffers[n][0] == 0 ) { - continue; - } - if( s_serveroptions.playerNameBuffers[n][0] == '-' ) { - continue; - } - if( s_serveroptions.gametype >= GT_TEAM ) { - Com_sprintf( buf, sizeof(buf), "addbot %s %i %s\n", s_serveroptions.playerNameBuffers[n], skill, - playerTeam_list[s_serveroptions.playerTeam[n].curvalue] ); - } - else { - Com_sprintf( buf, sizeof(buf), "addbot %s %i\n", s_serveroptions.playerNameBuffers[n], skill ); - } - trap_Cmd_ExecuteText( EXEC_APPEND, buf ); - } - - // set player's team - if( dedicated == 0 && s_serveroptions.gametype >= GT_TEAM ) { - trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait 5; team %s\n", playerTeam_list[s_serveroptions.playerTeam[0].curvalue] ) ); - } -} - - -/* -================= -ServerOptions_InitPlayerItems -================= -*/ -static void ServerOptions_InitPlayerItems( void ) { - int n; - int v; - - // init types - if( s_serveroptions.multiplayer ) { - v = 0; // open - } - else { - v = 1; // bot - } - - for( n = 0; n < PLAYER_SLOTS; n++ ) { - s_serveroptions.playerType[n].curvalue = v; - } - - if( s_serveroptions.multiplayer && (s_serveroptions.gametype < GT_TEAM) ) { - for( n = 8; n < PLAYER_SLOTS; n++ ) { - s_serveroptions.playerType[n].curvalue = 2; - } - } - - // if not a dedicated server, first slot is reserved for the human on the server - if( s_serveroptions.dedicated.curvalue == 0 ) { - // human - s_serveroptions.playerType[0].generic.flags |= QMF_INACTIVE; - s_serveroptions.playerType[0].curvalue = 0; - trap_Cvar_VariableStringBuffer( "name", s_serveroptions.playerNameBuffers[0], sizeof(s_serveroptions.playerNameBuffers[0]) ); - Q_CleanStr( s_serveroptions.playerNameBuffers[0] ); - } - - // init teams - if( s_serveroptions.gametype >= GT_TEAM ) { - for( n = 0; n < (PLAYER_SLOTS / 2); n++ ) { - s_serveroptions.playerTeam[n].curvalue = 0; - } - for( ; n < PLAYER_SLOTS; n++ ) { - s_serveroptions.playerTeam[n].curvalue = 1; - } - } - else { - for( n = 0; n < PLAYER_SLOTS; n++ ) { - s_serveroptions.playerTeam[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); - } - } -} - - -/* -================= -ServerOptions_SetPlayerItems -================= -*/ -static void ServerOptions_SetPlayerItems( void ) { - int start; - int n; - - // types -// for( n = 0; n < PLAYER_SLOTS; n++ ) { -// if( (!s_serveroptions.multiplayer) && (n > 0) && (s_serveroptions.playerType[n].curvalue == 0) ) { -// s_serveroptions.playerType[n].curvalue = 1; -// } -// } - - // names - if( s_serveroptions.dedicated.curvalue == 0 ) { - s_serveroptions.player0.string = "Human"; - s_serveroptions.playerName[0].generic.flags &= ~QMF_HIDDEN; - - start = 1; - } - else { - s_serveroptions.player0.string = "Open"; - start = 0; - } - for( n = start; n < PLAYER_SLOTS; n++ ) { - if( s_serveroptions.playerType[n].curvalue == 1 ) { - s_serveroptions.playerName[n].generic.flags &= ~(QMF_INACTIVE|QMF_HIDDEN); - } - else { - s_serveroptions.playerName[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); - } - } - - // teams - if( s_serveroptions.gametype < GT_TEAM ) { - return; - } - for( n = start; n < PLAYER_SLOTS; n++ ) { - if( s_serveroptions.playerType[n].curvalue == 2 ) { - s_serveroptions.playerTeam[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); - } - else { - s_serveroptions.playerTeam[n].generic.flags &= ~(QMF_INACTIVE|QMF_HIDDEN); - } - } -} - - -/* -================= -ServerOptions_Event -================= -*/ -static void ServerOptions_Event( void* ptr, int event ) { - switch( ((menucommon_s*)ptr)->id ) { - - //if( event != QM_ACTIVATED && event != QM_LOSTFOCUS) { - // return; - //} - case ID_PLAYER_TYPE: - if( event != QM_ACTIVATED ) { - break; - } - ServerOptions_SetPlayerItems(); - break; - - case ID_MAXCLIENTS: - case ID_DEDICATED: - ServerOptions_SetPlayerItems(); - break; - case ID_GO: - if( event != QM_ACTIVATED ) { - break; - } - ServerOptions_Start(); - break; - - case ID_STARTSERVERNEXT: - if( event != QM_ACTIVATED ) { - break; - } - break; - case ID_BACK: - if( event != QM_ACTIVATED ) { - break; - } - UI_PopMenu(); - break; - } -} - - -static void ServerOptions_PlayerNameEvent( void* ptr, int event ) { - int n; - - if( event != QM_ACTIVATED ) { - return; - } - n = ((menutext_s*)ptr)->generic.id; - s_serveroptions.newBotIndex = n; - UI_BotSelectMenu( s_serveroptions.playerNameBuffers[n] ); -} - - -/* -================= -ServerOptions_StatusBar -================= -*/ -static void ServerOptions_StatusBar( void* ptr ) { - switch( ((menucommon_s*)ptr)->id ) { - default: - UI_DrawString( 320, 440, "0 = NO LIMIT", UI_CENTER|UI_SMALLFONT, colorWhite ); - break; - } -} - - -/* -=============== -ServerOptions_LevelshotDraw -=============== -*/ -static void ServerOptions_LevelshotDraw( void *self ) { - menubitmap_s *b; - int x; - int y; - - // strange place for this, but it works - if( s_serveroptions.newBot ) { - Q_strncpyz( s_serveroptions.playerNameBuffers[s_serveroptions.newBotIndex], s_serveroptions.newBotName, 16 ); - s_serveroptions.newBot = qfalse; - } - - b = (menubitmap_s *)self; - - Bitmap_Draw( b ); - - x = b->generic.x; - y = b->generic.y + b->height; - UI_FillRect( x, y, b->width, 40, colorBlack ); - - x += b->width / 2; - y += 4; - UI_DrawString( x, y, s_serveroptions.mapnamebuffer, UI_CENTER|UI_SMALLFONT, color_orange ); - - y += SMALLCHAR_HEIGHT; - UI_DrawString( x, y, gametype_items[gametype_remap2[s_serveroptions.gametype]], UI_CENTER|UI_SMALLFONT, color_orange ); -} - - -static void ServerOptions_InitBotNames( void ) { - int count; - int n; - const char *arenaInfo; - const char *botInfo; - char *p; - char *bot; - char bots[MAX_INFO_STRING]; - - if( s_serveroptions.gametype >= GT_TEAM ) { - Q_strncpyz( s_serveroptions.playerNameBuffers[1], "grunt", 16 ); - Q_strncpyz( s_serveroptions.playerNameBuffers[2], "major", 16 ); - if( s_serveroptions.gametype == GT_TEAM ) { - Q_strncpyz( s_serveroptions.playerNameBuffers[3], "visor", 16 ); - } - else { - s_serveroptions.playerType[3].curvalue = 2; - } - s_serveroptions.playerType[4].curvalue = 2; - s_serveroptions.playerType[5].curvalue = 2; - - Q_strncpyz( s_serveroptions.playerNameBuffers[6], "sarge", 16 ); - Q_strncpyz( s_serveroptions.playerNameBuffers[7], "grunt", 16 ); - Q_strncpyz( s_serveroptions.playerNameBuffers[8], "major", 16 ); - if( s_serveroptions.gametype == GT_TEAM ) { - Q_strncpyz( s_serveroptions.playerNameBuffers[9], "visor", 16 ); - } - else { - s_serveroptions.playerType[9].curvalue = 2; - } - s_serveroptions.playerType[10].curvalue = 2; - s_serveroptions.playerType[11].curvalue = 2; - - return; - } - - count = 1; // skip the first slot, reserved for a human - - // get info for this map - arenaInfo = UI_GetArenaInfoByMap( s_serveroptions.mapnamebuffer ); - - // get the bot info - we'll seed with them if any are listed - Q_strncpyz( bots, Info_ValueForKey( arenaInfo, "bots" ), sizeof(bots) ); - p = &bots[0]; - while( *p && count < PLAYER_SLOTS ) { - //skip spaces - while( *p && *p == ' ' ) { - p++; - } - if( !p ) { - break; - } - - // mark start of bot name - bot = p; - - // skip until space of null - while( *p && *p != ' ' ) { - p++; - } - if( *p ) { - *p++ = 0; - } - - botInfo = UI_GetBotInfoByName( bot ); - bot = Info_ValueForKey( botInfo, "name" ); - - Q_strncpyz( s_serveroptions.playerNameBuffers[count], bot, sizeof(s_serveroptions.playerNameBuffers[count]) ); - count++; - } - - // set the rest of the bot slots to "---" - for( n = count; n < PLAYER_SLOTS; n++ ) { - strcpy( s_serveroptions.playerNameBuffers[n], "--------" ); - } - - // pad up to #8 as open slots - for( ;count < 8; count++ ) { - s_serveroptions.playerType[count].curvalue = 0; - } - - // close off the rest by default - for( ;count < PLAYER_SLOTS; count++ ) { - if( s_serveroptions.playerType[count].curvalue == 1 ) { - s_serveroptions.playerType[count].curvalue = 2; - } - } -} - - -/* -================= -ServerOptions_SetMenuItems -================= -*/ -static void ServerOptions_SetMenuItems( void ) { - static char picname[64]; - - switch( s_serveroptions.gametype ) { - case GT_FFA: - default: - Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ffa_fraglimit" ) ) ); - Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ffa_timelimit" ) ) ); - break; - - case GT_TOURNAMENT: - Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_tourney_fraglimit" ) ) ); - Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_tourney_timelimit" ) ) ); - break; - - case GT_TEAM: - Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_team_fraglimit" ) ) ); - Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_team_timelimit" ) ) ); - s_serveroptions.friendlyfire.curvalue = (int)Com_Clamp( 0, 1, trap_Cvar_VariableValue( "ui_team_friendly" ) ); - break; - - case GT_CTF: - Com_sprintf( s_serveroptions.flaglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 100, trap_Cvar_VariableValue( "ui_ctf_capturelimit" ) ) ); - Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ctf_timelimit" ) ) ); - s_serveroptions.friendlyfire.curvalue = (int)Com_Clamp( 0, 1, trap_Cvar_VariableValue( "ui_ctf_friendly" ) ); - break; - } - - Q_strncpyz( s_serveroptions.hostname.field.buffer, UI_Cvar_VariableString( "sv_hostname" ), sizeof( s_serveroptions.hostname.field.buffer ) ); - s_serveroptions.pure.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "sv_pure" ) ); - - // set the map pic - Com_sprintf( picname, 64, "levelshots/%s", s_startserver.maplist[s_startserver.currentmap] ); - s_serveroptions.mappic.generic.name = picname; - - // set the map name - strcpy( s_serveroptions.mapnamebuffer, s_startserver.mapname.string ); - Q_strupr( s_serveroptions.mapnamebuffer ); - - // get the player selections initialized - ServerOptions_InitPlayerItems(); - ServerOptions_SetPlayerItems(); - - // seed bot names - ServerOptions_InitBotNames(); - ServerOptions_SetPlayerItems(); -} - -/* -================= -PlayerName_Draw -================= -*/ -static void PlayerName_Draw( void *item ) { - menutext_s *s; - float *color; - int x, y; - int style; - qboolean focus; - - s = (menutext_s *)item; - - x = s->generic.x; - y = s->generic.y; - - style = UI_SMALLFONT; - focus = (s->generic.parent->cursor == s->generic.menuPosition); - - if ( s->generic.flags & QMF_GRAYED ) - color = text_color_disabled; - else if ( focus ) - { - color = text_color_highlight; - style |= UI_PULSE; - } - else if ( s->generic.flags & QMF_BLINK ) - { - color = text_color_highlight; - style |= UI_BLINK; - } - else - color = text_color_normal; - - if ( focus ) - { - // draw cursor - UI_FillRect( s->generic.left, s->generic.top, s->generic.right-s->generic.left+1, s->generic.bottom-s->generic.top+1, listbar_color ); - UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); - } - - UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, style|UI_RIGHT, color ); - UI_DrawString( x + SMALLCHAR_WIDTH, y, s->string, style|UI_LEFT, color ); -} - - -/* -================= -ServerOptions_MenuInit -================= -*/ -#define OPTIONS_X 456 - -static void ServerOptions_MenuInit( qboolean multiplayer ) { - int y; - int n; - - memset( &s_serveroptions, 0 ,sizeof(serveroptions_t) ); - s_serveroptions.multiplayer = multiplayer; - s_serveroptions.gametype = (int)Com_Clamp( 0, 5, trap_Cvar_VariableValue( "g_gameType" ) ); - s_serveroptions.punkbuster.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "sv_punkbuster" ) ); - - ServerOptions_Cache(); - - s_serveroptions.menu.wrapAround = qtrue; - s_serveroptions.menu.fullscreen = qtrue; - - s_serveroptions.banner.generic.type = MTYPE_BTEXT; - s_serveroptions.banner.generic.x = 320; - s_serveroptions.banner.generic.y = 16; - s_serveroptions.banner.string = "GAME SERVER"; - s_serveroptions.banner.color = color_white; - s_serveroptions.banner.style = UI_CENTER; - - s_serveroptions.mappic.generic.type = MTYPE_BITMAP; - s_serveroptions.mappic.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - s_serveroptions.mappic.generic.x = 352; - s_serveroptions.mappic.generic.y = 80; - s_serveroptions.mappic.width = 160; - s_serveroptions.mappic.height = 120; - s_serveroptions.mappic.errorpic = GAMESERVER_UNKNOWNMAP; - s_serveroptions.mappic.generic.ownerdraw = ServerOptions_LevelshotDraw; - - s_serveroptions.picframe.generic.type = MTYPE_BITMAP; - s_serveroptions.picframe.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE|QMF_HIGHLIGHT; - s_serveroptions.picframe.generic.x = 352 - 38; - s_serveroptions.picframe.generic.y = 80 - 40; - s_serveroptions.picframe.width = 320; - s_serveroptions.picframe.height = 320; - s_serveroptions.picframe.focuspic = GAMESERVER_SELECT; - - y = 272; - if( s_serveroptions.gametype != GT_CTF ) { - s_serveroptions.fraglimit.generic.type = MTYPE_FIELD; - s_serveroptions.fraglimit.generic.name = "Frag Limit:"; - s_serveroptions.fraglimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.fraglimit.generic.x = OPTIONS_X; - s_serveroptions.fraglimit.generic.y = y; - s_serveroptions.fraglimit.generic.statusbar = ServerOptions_StatusBar; - s_serveroptions.fraglimit.field.widthInChars = 3; - s_serveroptions.fraglimit.field.maxchars = 3; - } - else { - s_serveroptions.flaglimit.generic.type = MTYPE_FIELD; - s_serveroptions.flaglimit.generic.name = "Capture Limit:"; - s_serveroptions.flaglimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.flaglimit.generic.x = OPTIONS_X; - s_serveroptions.flaglimit.generic.y = y; - s_serveroptions.flaglimit.generic.statusbar = ServerOptions_StatusBar; - s_serveroptions.flaglimit.field.widthInChars = 3; - s_serveroptions.flaglimit.field.maxchars = 3; - } - - y += BIGCHAR_HEIGHT+2; - s_serveroptions.timelimit.generic.type = MTYPE_FIELD; - s_serveroptions.timelimit.generic.name = "Time Limit:"; - s_serveroptions.timelimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.timelimit.generic.x = OPTIONS_X; - s_serveroptions.timelimit.generic.y = y; - s_serveroptions.timelimit.generic.statusbar = ServerOptions_StatusBar; - s_serveroptions.timelimit.field.widthInChars = 3; - s_serveroptions.timelimit.field.maxchars = 3; - - if( s_serveroptions.gametype >= GT_TEAM ) { - y += BIGCHAR_HEIGHT+2; - s_serveroptions.friendlyfire.generic.type = MTYPE_RADIOBUTTON; - s_serveroptions.friendlyfire.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.friendlyfire.generic.x = OPTIONS_X; - s_serveroptions.friendlyfire.generic.y = y; - s_serveroptions.friendlyfire.generic.name = "Friendly Fire:"; - } - - y += BIGCHAR_HEIGHT+2; - s_serveroptions.pure.generic.type = MTYPE_RADIOBUTTON; - s_serveroptions.pure.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.pure.generic.x = OPTIONS_X; - s_serveroptions.pure.generic.y = y; - s_serveroptions.pure.generic.name = "Pure Server:"; - - if( s_serveroptions.multiplayer ) { - y += BIGCHAR_HEIGHT+2; - s_serveroptions.dedicated.generic.type = MTYPE_SPINCONTROL; - s_serveroptions.dedicated.generic.id = ID_DEDICATED; - s_serveroptions.dedicated.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.dedicated.generic.callback = ServerOptions_Event; - s_serveroptions.dedicated.generic.x = OPTIONS_X; - s_serveroptions.dedicated.generic.y = y; - s_serveroptions.dedicated.generic.name = "Dedicated:"; - s_serveroptions.dedicated.itemnames = dedicated_list; - } - - if( s_serveroptions.multiplayer ) { - y += BIGCHAR_HEIGHT+2; - s_serveroptions.hostname.generic.type = MTYPE_FIELD; - s_serveroptions.hostname.generic.name = "Hostname:"; - s_serveroptions.hostname.generic.flags = QMF_SMALLFONT; - s_serveroptions.hostname.generic.x = OPTIONS_X; - s_serveroptions.hostname.generic.y = y; - s_serveroptions.hostname.field.widthInChars = 18; - s_serveroptions.hostname.field.maxchars = 64; - } - - y += BIGCHAR_HEIGHT+2; - s_serveroptions.punkbuster.generic.type = MTYPE_SPINCONTROL; - s_serveroptions.punkbuster.generic.name = "Punkbuster:"; - s_serveroptions.punkbuster.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.punkbuster.generic.id = 0; - s_serveroptions.punkbuster.generic.x = OPTIONS_X; - s_serveroptions.punkbuster.generic.y = y; - s_serveroptions.punkbuster.itemnames = punkbuster_items; - - y = 80; - s_serveroptions.botSkill.generic.type = MTYPE_SPINCONTROL; - s_serveroptions.botSkill.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.botSkill.generic.name = "Bot Skill: "; - s_serveroptions.botSkill.generic.x = 32 + (strlen(s_serveroptions.botSkill.generic.name) + 2 ) * SMALLCHAR_WIDTH; - s_serveroptions.botSkill.generic.y = y; - s_serveroptions.botSkill.itemnames = botSkill_list; - s_serveroptions.botSkill.curvalue = 1; - - y += ( 2 * SMALLCHAR_HEIGHT ); - s_serveroptions.player0.generic.type = MTYPE_TEXT; - s_serveroptions.player0.generic.flags = QMF_SMALLFONT; - s_serveroptions.player0.generic.x = 32 + SMALLCHAR_WIDTH; - s_serveroptions.player0.generic.y = y; - s_serveroptions.player0.color = color_orange; - s_serveroptions.player0.style = UI_LEFT|UI_SMALLFONT; - - for( n = 0; n < PLAYER_SLOTS; n++ ) { - s_serveroptions.playerType[n].generic.type = MTYPE_SPINCONTROL; - s_serveroptions.playerType[n].generic.flags = QMF_SMALLFONT; - s_serveroptions.playerType[n].generic.id = ID_PLAYER_TYPE; - s_serveroptions.playerType[n].generic.callback = ServerOptions_Event; - s_serveroptions.playerType[n].generic.x = 32; - s_serveroptions.playerType[n].generic.y = y; - s_serveroptions.playerType[n].itemnames = playerType_list; - - s_serveroptions.playerName[n].generic.type = MTYPE_TEXT; - s_serveroptions.playerName[n].generic.flags = QMF_SMALLFONT; - s_serveroptions.playerName[n].generic.x = 96; - s_serveroptions.playerName[n].generic.y = y; - s_serveroptions.playerName[n].generic.callback = ServerOptions_PlayerNameEvent; - s_serveroptions.playerName[n].generic.id = n; - s_serveroptions.playerName[n].generic.ownerdraw = PlayerName_Draw; - s_serveroptions.playerName[n].color = color_orange; - s_serveroptions.playerName[n].style = UI_SMALLFONT; - s_serveroptions.playerName[n].string = s_serveroptions.playerNameBuffers[n]; - s_serveroptions.playerName[n].generic.top = s_serveroptions.playerName[n].generic.y; - s_serveroptions.playerName[n].generic.bottom = s_serveroptions.playerName[n].generic.y + SMALLCHAR_HEIGHT; - s_serveroptions.playerName[n].generic.left = s_serveroptions.playerName[n].generic.x - SMALLCHAR_HEIGHT/ 2; - s_serveroptions.playerName[n].generic.right = s_serveroptions.playerName[n].generic.x + 16 * SMALLCHAR_WIDTH; - - s_serveroptions.playerTeam[n].generic.type = MTYPE_SPINCONTROL; - s_serveroptions.playerTeam[n].generic.flags = QMF_SMALLFONT; - s_serveroptions.playerTeam[n].generic.x = 240; - s_serveroptions.playerTeam[n].generic.y = y; - s_serveroptions.playerTeam[n].itemnames = playerTeam_list; - - y += ( SMALLCHAR_HEIGHT + 4 ); - } - - s_serveroptions.back.generic.type = MTYPE_BITMAP; - s_serveroptions.back.generic.name = GAMESERVER_BACK0; - s_serveroptions.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_serveroptions.back.generic.callback = ServerOptions_Event; - s_serveroptions.back.generic.id = ID_BACK; - s_serveroptions.back.generic.x = 0; - s_serveroptions.back.generic.y = 480-64; - s_serveroptions.back.width = 128; - s_serveroptions.back.height = 64; - s_serveroptions.back.focuspic = GAMESERVER_BACK1; - - s_serveroptions.next.generic.type = MTYPE_BITMAP; - s_serveroptions.next.generic.name = GAMESERVER_NEXT0; - s_serveroptions.next.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE|QMF_GRAYED|QMF_HIDDEN; - s_serveroptions.next.generic.callback = ServerOptions_Event; - s_serveroptions.next.generic.id = ID_STARTSERVERNEXT; - s_serveroptions.next.generic.x = 640; - s_serveroptions.next.generic.y = 480-64-72; - s_serveroptions.next.generic.statusbar = ServerOptions_StatusBar; - s_serveroptions.next.width = 128; - s_serveroptions.next.height = 64; - s_serveroptions.next.focuspic = GAMESERVER_NEXT1; - - s_serveroptions.go.generic.type = MTYPE_BITMAP; - s_serveroptions.go.generic.name = GAMESERVER_FIGHT0; - s_serveroptions.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_serveroptions.go.generic.callback = ServerOptions_Event; - s_serveroptions.go.generic.id = ID_GO; - s_serveroptions.go.generic.x = 640; - s_serveroptions.go.generic.y = 480-64; - s_serveroptions.go.width = 128; - s_serveroptions.go.height = 64; - s_serveroptions.go.focuspic = GAMESERVER_FIGHT1; - - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.banner ); - - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.mappic ); - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.picframe ); - - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.botSkill ); - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.player0 ); - for( n = 0; n < PLAYER_SLOTS; n++ ) { - if( n != 0 ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerType[n] ); - } - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerName[n] ); - if( s_serveroptions.gametype >= GT_TEAM ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerTeam[n] ); - } - } - - if( s_serveroptions.gametype != GT_CTF ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.fraglimit ); - } - else { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.flaglimit ); - } - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.timelimit ); - if( s_serveroptions.gametype >= GT_TEAM ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.friendlyfire ); - } - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.pure ); - if( s_serveroptions.multiplayer ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.dedicated ); - } - if( s_serveroptions.multiplayer ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.hostname ); - } - - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.back ); - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.next ); - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.go ); - - Menu_AddItem( &s_serveroptions.menu, (void*) &s_serveroptions.punkbuster ); - - ServerOptions_SetMenuItems(); -} - -/* -================= -ServerOptions_Cache -================= -*/ -void ServerOptions_Cache( void ) { - trap_R_RegisterShaderNoMip( GAMESERVER_BACK0 ); - trap_R_RegisterShaderNoMip( GAMESERVER_BACK1 ); - trap_R_RegisterShaderNoMip( GAMESERVER_FIGHT0 ); - trap_R_RegisterShaderNoMip( GAMESERVER_FIGHT1 ); - trap_R_RegisterShaderNoMip( GAMESERVER_SELECT ); - trap_R_RegisterShaderNoMip( GAMESERVER_UNKNOWNMAP ); -} - - -/* -================= -UI_ServerOptionsMenu -================= -*/ -static void UI_ServerOptionsMenu( qboolean multiplayer ) { - ServerOptions_MenuInit( multiplayer ); - UI_PushMenu( &s_serveroptions.menu ); -} - - - -/* -============================================================================= - -BOT SELECT MENU ***** - -============================================================================= -*/ - - -#define BOTSELECT_BACK0 "menu/art/back_0" -#define BOTSELECT_BACK1 "menu/art/back_1" -#define BOTSELECT_ACCEPT0 "menu/art/accept_0" -#define BOTSELECT_ACCEPT1 "menu/art/accept_1" -#define BOTSELECT_SELECT "menu/art/opponents_select" -#define BOTSELECT_SELECTED "menu/art/opponents_selected" -#define BOTSELECT_ARROWS "menu/art/gs_arrows_0" -#define BOTSELECT_ARROWSL "menu/art/gs_arrows_l" -#define BOTSELECT_ARROWSR "menu/art/gs_arrows_r" - -#define PLAYERGRID_COLS 4 -#define PLAYERGRID_ROWS 4 -#define MAX_MODELSPERPAGE (PLAYERGRID_ROWS * PLAYERGRID_COLS) - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - - menubitmap_s pics[MAX_MODELSPERPAGE]; - menubitmap_s picbuttons[MAX_MODELSPERPAGE]; - menutext_s picnames[MAX_MODELSPERPAGE]; - - menubitmap_s arrows; - menubitmap_s left; - menubitmap_s right; - - menubitmap_s go; - menubitmap_s back; - - int numBots; - int modelpage; - int numpages; - int selectedmodel; - int sortedBotNums[MAX_BOTS]; - char boticons[MAX_MODELSPERPAGE][MAX_QPATH]; - char botnames[MAX_MODELSPERPAGE][16]; -} botSelectInfo_t; - -static botSelectInfo_t botSelectInfo; - - -/* -================= -UI_BotSelectMenu_SortCompare -================= -*/ -static int QDECL UI_BotSelectMenu_SortCompare( const void *arg1, const void *arg2 ) { - int num1, num2; - const char *info1, *info2; - const char *name1, *name2; - - num1 = *(int *)arg1; - num2 = *(int *)arg2; - - info1 = UI_GetBotInfoByNumber( num1 ); - info2 = UI_GetBotInfoByNumber( num2 ); - - name1 = Info_ValueForKey( info1, "name" ); - name2 = Info_ValueForKey( info2, "name" ); - - return Q_stricmp( name1, name2 ); -} - - -/* -================= -UI_BotSelectMenu_BuildList -================= -*/ -static void UI_BotSelectMenu_BuildList( void ) { - int n; - - botSelectInfo.modelpage = 0; - botSelectInfo.numBots = UI_GetNumBots(); - botSelectInfo.numpages = botSelectInfo.numBots / MAX_MODELSPERPAGE; - if( botSelectInfo.numBots % MAX_MODELSPERPAGE ) { - botSelectInfo.numpages++; - } - - // initialize the array - for( n = 0; n < botSelectInfo.numBots; n++ ) { - botSelectInfo.sortedBotNums[n] = n; - } - - // now sort it - qsort( botSelectInfo.sortedBotNums, botSelectInfo.numBots, sizeof(botSelectInfo.sortedBotNums[0]), UI_BotSelectMenu_SortCompare ); -} - - -/* -================= -ServerPlayerIcon -================= -*/ -static void ServerPlayerIcon( const char *modelAndSkin, char *iconName, int iconNameMaxSize ) { - char *skin; - char model[MAX_QPATH]; - - Q_strncpyz( model, modelAndSkin, sizeof(model)); - skin = Q_strrchr( model, '/' ); - if ( skin ) { - *skin++ = '\0'; - } - else { - skin = "default"; - } - - Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_%s.tga", model, skin ); - - if( !trap_R_RegisterShaderNoMip( iconName ) && Q_stricmp( skin, "default" ) != 0 ) { - Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_default.tga", model ); - } -} - - -/* -================= -UI_BotSelectMenu_UpdateGrid -================= -*/ -static void UI_BotSelectMenu_UpdateGrid( void ) { - const char *info; - int i; - int j; - - j = botSelectInfo.modelpage * MAX_MODELSPERPAGE; - for( i = 0; i < (PLAYERGRID_ROWS * PLAYERGRID_COLS); i++, j++) { - if( j < botSelectInfo.numBots ) { - info = UI_GetBotInfoByNumber( botSelectInfo.sortedBotNums[j] ); - ServerPlayerIcon( Info_ValueForKey( info, "model" ), botSelectInfo.boticons[i], MAX_QPATH ); - Q_strncpyz( botSelectInfo.botnames[i], Info_ValueForKey( info, "name" ), 16 ); - Q_CleanStr( botSelectInfo.botnames[i] ); - botSelectInfo.pics[i].generic.name = botSelectInfo.boticons[i]; - if( BotAlreadySelected( botSelectInfo.botnames[i] ) ) { - botSelectInfo.picnames[i].color = color_red; - } - else { - botSelectInfo.picnames[i].color = color_orange; - } - botSelectInfo.picbuttons[i].generic.flags &= ~QMF_INACTIVE; - } - else { - // dead slot - botSelectInfo.pics[i].generic.name = NULL; - botSelectInfo.picbuttons[i].generic.flags |= QMF_INACTIVE; - botSelectInfo.botnames[i][0] = 0; - } - - botSelectInfo.pics[i].generic.flags &= ~QMF_HIGHLIGHT; - botSelectInfo.pics[i].shader = 0; - botSelectInfo.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; - } - - // set selected model - i = botSelectInfo.selectedmodel % MAX_MODELSPERPAGE; - botSelectInfo.pics[i].generic.flags |= QMF_HIGHLIGHT; - botSelectInfo.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; - - if( botSelectInfo.numpages > 1 ) { - if( botSelectInfo.modelpage > 0 ) { - botSelectInfo.left.generic.flags &= ~QMF_INACTIVE; - } - else { - botSelectInfo.left.generic.flags |= QMF_INACTIVE; - } - - if( botSelectInfo.modelpage < (botSelectInfo.numpages - 1) ) { - botSelectInfo.right.generic.flags &= ~QMF_INACTIVE; - } - else { - botSelectInfo.right.generic.flags |= QMF_INACTIVE; - } - } - else { - // hide left/right markers - botSelectInfo.left.generic.flags |= QMF_INACTIVE; - botSelectInfo.right.generic.flags |= QMF_INACTIVE; - } -} - - -/* -================= -UI_BotSelectMenu_Default -================= -*/ -static void UI_BotSelectMenu_Default( char *bot ) { - const char *botInfo; - const char *test; - int n; - int i; - - for( n = 0; n < botSelectInfo.numBots; n++ ) { - botInfo = UI_GetBotInfoByNumber( n ); - test = Info_ValueForKey( botInfo, "name" ); - if( Q_stricmp( bot, test ) == 0 ) { - break; - } - } - if( n == botSelectInfo.numBots ) { - botSelectInfo.selectedmodel = 0; - return; - } - - for( i = 0; i < botSelectInfo.numBots; i++ ) { - if( botSelectInfo.sortedBotNums[i] == n ) { - break; - } - } - if( i == botSelectInfo.numBots ) { - botSelectInfo.selectedmodel = 0; - return; - } - - botSelectInfo.selectedmodel = i; -} - - -/* -================= -UI_BotSelectMenu_LeftEvent -================= -*/ -static void UI_BotSelectMenu_LeftEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - if( botSelectInfo.modelpage > 0 ) { - botSelectInfo.modelpage--; - botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE; - UI_BotSelectMenu_UpdateGrid(); - } -} - - -/* -================= -UI_BotSelectMenu_RightEvent -================= -*/ -static void UI_BotSelectMenu_RightEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - if( botSelectInfo.modelpage < botSelectInfo.numpages - 1 ) { - botSelectInfo.modelpage++; - botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE; - UI_BotSelectMenu_UpdateGrid(); - } -} - - -/* -================= -UI_BotSelectMenu_BotEvent -================= -*/ -static void UI_BotSelectMenu_BotEvent( void* ptr, int event ) { - int i; - - if( event != QM_ACTIVATED ) { - return; - } - - for( i = 0; i < (PLAYERGRID_ROWS * PLAYERGRID_COLS); i++ ) { - botSelectInfo.pics[i].generic.flags &= ~QMF_HIGHLIGHT; - botSelectInfo.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; - } - - // set selected - i = ((menucommon_s*)ptr)->id; - botSelectInfo.pics[i].generic.flags |= QMF_HIGHLIGHT; - botSelectInfo.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; - botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE + i; -} - - -/* -================= -UI_BotSelectMenu_BackEvent -================= -*/ -static void UI_BotSelectMenu_BackEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - UI_PopMenu(); -} - - -/* -================= -UI_BotSelectMenu_SelectEvent -================= -*/ -static void UI_BotSelectMenu_SelectEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - UI_PopMenu(); - - s_serveroptions.newBot = qtrue; - Q_strncpyz( s_serveroptions.newBotName, botSelectInfo.botnames[botSelectInfo.selectedmodel % MAX_MODELSPERPAGE], 16 ); -} - - -/* -================= -UI_BotSelectMenu_Cache -================= -*/ -void UI_BotSelectMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( BOTSELECT_BACK0 ); - trap_R_RegisterShaderNoMip( BOTSELECT_BACK1 ); - trap_R_RegisterShaderNoMip( BOTSELECT_ACCEPT0 ); - trap_R_RegisterShaderNoMip( BOTSELECT_ACCEPT1 ); - trap_R_RegisterShaderNoMip( BOTSELECT_SELECT ); - trap_R_RegisterShaderNoMip( BOTSELECT_SELECTED ); - trap_R_RegisterShaderNoMip( BOTSELECT_ARROWS ); - trap_R_RegisterShaderNoMip( BOTSELECT_ARROWSL ); - trap_R_RegisterShaderNoMip( BOTSELECT_ARROWSR ); -} - - -static void UI_BotSelectMenu_Init( char *bot ) { - int i, j, k; - int x, y; - - memset( &botSelectInfo, 0 ,sizeof(botSelectInfo) ); - botSelectInfo.menu.wrapAround = qtrue; - botSelectInfo.menu.fullscreen = qtrue; - - UI_BotSelectMenu_Cache(); - - botSelectInfo.banner.generic.type = MTYPE_BTEXT; - botSelectInfo.banner.generic.x = 320; - botSelectInfo.banner.generic.y = 16; - botSelectInfo.banner.string = "SELECT BOT"; - botSelectInfo.banner.color = color_white; - botSelectInfo.banner.style = UI_CENTER; - - y = 80; - for( i = 0, k = 0; i < PLAYERGRID_ROWS; i++) { - x = 180; - for( j = 0; j < PLAYERGRID_COLS; j++, k++ ) { - botSelectInfo.pics[k].generic.type = MTYPE_BITMAP; - botSelectInfo.pics[k].generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - botSelectInfo.pics[k].generic.x = x; - botSelectInfo.pics[k].generic.y = y; - botSelectInfo.pics[k].generic.name = botSelectInfo.boticons[k]; - botSelectInfo.pics[k].width = 64; - botSelectInfo.pics[k].height = 64; - botSelectInfo.pics[k].focuspic = BOTSELECT_SELECTED; - botSelectInfo.pics[k].focuscolor = colorRed; - - botSelectInfo.picbuttons[k].generic.type = MTYPE_BITMAP; - botSelectInfo.picbuttons[k].generic.flags = QMF_LEFT_JUSTIFY|QMF_NODEFAULTINIT|QMF_PULSEIFFOCUS; - botSelectInfo.picbuttons[k].generic.callback = UI_BotSelectMenu_BotEvent; - botSelectInfo.picbuttons[k].generic.id = k; - botSelectInfo.picbuttons[k].generic.x = x - 16; - botSelectInfo.picbuttons[k].generic.y = y - 16; - botSelectInfo.picbuttons[k].generic.left = x; - botSelectInfo.picbuttons[k].generic.top = y; - botSelectInfo.picbuttons[k].generic.right = x + 64; - botSelectInfo.picbuttons[k].generic.bottom = y + 64; - botSelectInfo.picbuttons[k].width = 128; - botSelectInfo.picbuttons[k].height = 128; - botSelectInfo.picbuttons[k].focuspic = BOTSELECT_SELECT; - botSelectInfo.picbuttons[k].focuscolor = colorRed; - - botSelectInfo.picnames[k].generic.type = MTYPE_TEXT; - botSelectInfo.picnames[k].generic.flags = QMF_SMALLFONT; - botSelectInfo.picnames[k].generic.x = x + 32; - botSelectInfo.picnames[k].generic.y = y + 64; - botSelectInfo.picnames[k].string = botSelectInfo.botnames[k]; - botSelectInfo.picnames[k].color = color_orange; - botSelectInfo.picnames[k].style = UI_CENTER|UI_SMALLFONT; - - x += (64 + 6); - } - y += (64 + SMALLCHAR_HEIGHT + 6); - } - - botSelectInfo.arrows.generic.type = MTYPE_BITMAP; - botSelectInfo.arrows.generic.name = BOTSELECT_ARROWS; - botSelectInfo.arrows.generic.flags = QMF_INACTIVE; - botSelectInfo.arrows.generic.x = 260; - botSelectInfo.arrows.generic.y = 440; - botSelectInfo.arrows.width = 128; - botSelectInfo.arrows.height = 32; - - botSelectInfo.left.generic.type = MTYPE_BITMAP; - botSelectInfo.left.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - botSelectInfo.left.generic.callback = UI_BotSelectMenu_LeftEvent; - botSelectInfo.left.generic.x = 260; - botSelectInfo.left.generic.y = 440; - botSelectInfo.left.width = 64; - botSelectInfo.left.height = 32; - botSelectInfo.left.focuspic = BOTSELECT_ARROWSL; - - botSelectInfo.right.generic.type = MTYPE_BITMAP; - botSelectInfo.right.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - botSelectInfo.right.generic.callback = UI_BotSelectMenu_RightEvent; - botSelectInfo.right.generic.x = 321; - botSelectInfo.right.generic.y = 440; - botSelectInfo.right.width = 64; - botSelectInfo.right.height = 32; - botSelectInfo.right.focuspic = BOTSELECT_ARROWSR; - - botSelectInfo.back.generic.type = MTYPE_BITMAP; - botSelectInfo.back.generic.name = BOTSELECT_BACK0; - botSelectInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - botSelectInfo.back.generic.callback = UI_BotSelectMenu_BackEvent; - botSelectInfo.back.generic.x = 0; - botSelectInfo.back.generic.y = 480-64; - botSelectInfo.back.width = 128; - botSelectInfo.back.height = 64; - botSelectInfo.back.focuspic = BOTSELECT_BACK1; - - botSelectInfo.go.generic.type = MTYPE_BITMAP; - botSelectInfo.go.generic.name = BOTSELECT_ACCEPT0; - botSelectInfo.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - botSelectInfo.go.generic.callback = UI_BotSelectMenu_SelectEvent; - botSelectInfo.go.generic.x = 640; - botSelectInfo.go.generic.y = 480-64; - botSelectInfo.go.width = 128; - botSelectInfo.go.height = 64; - botSelectInfo.go.focuspic = BOTSELECT_ACCEPT1; - - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.banner ); - for( i = 0; i < MAX_MODELSPERPAGE; i++ ) { - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.pics[i] ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.picbuttons[i] ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.picnames[i] ); - } - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.arrows ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.left ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.right ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.back ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.go ); - - UI_BotSelectMenu_BuildList(); - UI_BotSelectMenu_Default( bot ); - botSelectInfo.modelpage = botSelectInfo.selectedmodel / MAX_MODELSPERPAGE; - UI_BotSelectMenu_UpdateGrid(); -} - - -/* -================= -UI_BotSelectMenu -================= -*/ -void UI_BotSelectMenu( char *bot ) { - UI_BotSelectMenu_Init( bot ); - UI_PushMenu( &botSelectInfo.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena 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. + +Quake III Arena 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 Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +============================================================================= + +START SERVER MENU ***** + +============================================================================= +*/ + + +#include "ui_local.h" + + +#define GAMESERVER_BACK0 "menu/art/back_0" +#define GAMESERVER_BACK1 "menu/art/back_1" +#define GAMESERVER_NEXT0 "menu/art/next_0" +#define GAMESERVER_NEXT1 "menu/art/next_1" +#define GAMESERVER_FRAMEL "menu/art/frame2_l" +#define GAMESERVER_FRAMER "menu/art/frame1_r" +#define GAMESERVER_SELECT "menu/art/maps_select" +#define GAMESERVER_SELECTED "menu/art/maps_selected" +#define GAMESERVER_FIGHT0 "menu/art/fight_0" +#define GAMESERVER_FIGHT1 "menu/art/fight_1" +#define GAMESERVER_UNKNOWNMAP "menu/art/unknownmap" +#define GAMESERVER_ARROWS "menu/art/gs_arrows_0" +#define GAMESERVER_ARROWSL "menu/art/gs_arrows_l" +#define GAMESERVER_ARROWSR "menu/art/gs_arrows_r" + +#define MAX_MAPROWS 2 +#define MAX_MAPCOLS 2 +#define MAX_MAPSPERPAGE 4 + +#define MAX_SERVERSTEXT 8192 + +#define MAX_SERVERMAPS 64 +#define MAX_NAMELENGTH 16 + +#define ID_GAMETYPE 10 +#define ID_PICTURES 11 // 12, 13, 14 +#define ID_PREVPAGE 15 +#define ID_NEXTPAGE 16 +#define ID_STARTSERVERBACK 17 +#define ID_STARTSERVERNEXT 18 + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + + menulist_s gametype; + menubitmap_s mappics[MAX_MAPSPERPAGE]; + menubitmap_s mapbuttons[MAX_MAPSPERPAGE]; + menubitmap_s arrows; + menubitmap_s prevpage; + menubitmap_s nextpage; + menubitmap_s back; + menubitmap_s next; + + menutext_s mapname; + menubitmap_s item_null; + + qboolean multiplayer; + int currentmap; + int nummaps; + int page; + int maxpages; + char maplist[MAX_SERVERMAPS][MAX_NAMELENGTH]; + int mapGamebits[MAX_SERVERMAPS]; +} startserver_t; + +static startserver_t s_startserver; + +static const char *gametype_items[] = { + "Free For All", + "Team Deathmatch", + "Tournament", + "Capture the Flag", + 0 +}; + +static int gametype_remap[] = {GT_FFA, GT_TEAM, GT_TOURNAMENT, GT_CTF}; +static int gametype_remap2[] = {0, 2, 0, 1, 3}; + +// use ui_servers2.c definition +extern const char* punkbuster_items[]; + +static void UI_ServerOptionsMenu( qboolean multiplayer ); + + +/* +================= +GametypeBits +================= +*/ +static int GametypeBits( char *string ) { + int bits; + char *p; + char *token; + + bits = 0; + p = string; + while( 1 ) { + token = COM_ParseExt( &p, qfalse ); + if( token[0] == 0 ) { + break; + } + + if( Q_stricmp( token, "ffa" ) == 0 ) { + bits |= 1 << GT_FFA; + continue; + } + + if( Q_stricmp( token, "tourney" ) == 0 ) { + bits |= 1 << GT_TOURNAMENT; + continue; + } + + if( Q_stricmp( token, "single" ) == 0 ) { + bits |= 1 << GT_SINGLE_PLAYER; + continue; + } + + if( Q_stricmp( token, "team" ) == 0 ) { + bits |= 1 << GT_TEAM; + continue; + } + + if( Q_stricmp( token, "ctf" ) == 0 ) { + bits |= 1 << GT_CTF; + continue; + } + } + + return bits; +} + + +/* +================= +StartServer_Update +================= +*/ +static void StartServer_Update( void ) { + int i; + int top; + static char picname[MAX_MAPSPERPAGE][64]; + + top = s_startserver.page*MAX_MAPSPERPAGE; + + for (i=0; i= s_startserver.nummaps) + break; + + Com_sprintf( picname[i], sizeof(picname[i]), "levelshots/%s", s_startserver.maplist[top+i] ); + + s_startserver.mappics[i].generic.flags &= ~QMF_HIGHLIGHT; + s_startserver.mappics[i].generic.name = picname[i]; + s_startserver.mappics[i].shader = 0; + + // reset + s_startserver.mapbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; + s_startserver.mapbuttons[i].generic.flags &= ~QMF_INACTIVE; + } + + for (; i=0 && i < MAX_MAPSPERPAGE ) + { + s_startserver.mappics[i].generic.flags |= QMF_HIGHLIGHT; + s_startserver.mapbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; + } + + // set the map name + strcpy( s_startserver.mapname.string, s_startserver.maplist[s_startserver.currentmap] ); + } + + Q_strupr( s_startserver.mapname.string ); +} + + +/* +================= +StartServer_MapEvent +================= +*/ +static void StartServer_MapEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED) { + return; + } + + s_startserver.currentmap = (s_startserver.page*MAX_MAPSPERPAGE) + (((menucommon_s*)ptr)->id - ID_PICTURES); + StartServer_Update(); +} + + +/* +================= +StartServer_GametypeEvent +================= +*/ +static void StartServer_GametypeEvent( void* ptr, int event ) { + int i; + int count; + int gamebits; + int matchbits; + const char *info; + + if( event != QM_ACTIVATED) { + return; + } + + count = UI_GetNumArenas(); + s_startserver.nummaps = 0; + matchbits = 1 << gametype_remap[s_startserver.gametype.curvalue]; + if( gametype_remap[s_startserver.gametype.curvalue] == GT_FFA ) { + matchbits |= ( 1 << GT_SINGLE_PLAYER ); + } + for( i = 0; i < count; i++ ) { + info = UI_GetArenaInfoByNumber( i ); + + gamebits = GametypeBits( Info_ValueForKey( info, "type") ); + if( !( gamebits & matchbits ) ) { + continue; + } + + Q_strncpyz( s_startserver.maplist[s_startserver.nummaps], Info_ValueForKey( info, "map"), MAX_NAMELENGTH ); + Q_strupr( s_startserver.maplist[s_startserver.nummaps] ); + s_startserver.mapGamebits[s_startserver.nummaps] = gamebits; + s_startserver.nummaps++; + } + s_startserver.maxpages = (s_startserver.nummaps + MAX_MAPSPERPAGE-1)/MAX_MAPSPERPAGE; + s_startserver.page = 0; + s_startserver.currentmap = 0; + + StartServer_Update(); +} + + +/* +================= +StartServer_MenuEvent +================= +*/ +static void StartServer_MenuEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_PREVPAGE: + if( s_startserver.page > 0 ) { + s_startserver.page--; + StartServer_Update(); + } + break; + + case ID_NEXTPAGE: + if( s_startserver.page < s_startserver.maxpages - 1 ) { + s_startserver.page++; + StartServer_Update(); + } + break; + + case ID_STARTSERVERNEXT: + trap_Cvar_SetValue( "g_gameType", gametype_remap[s_startserver.gametype.curvalue] ); + UI_ServerOptionsMenu( s_startserver.multiplayer ); + break; + + case ID_STARTSERVERBACK: + UI_PopMenu(); + break; + } +} + + +/* +=============== +StartServer_LevelshotDraw +=============== +*/ +static void StartServer_LevelshotDraw( void *self ) { + menubitmap_s *b; + int x; + int y; + int w; + int h; + int n; + + b = (menubitmap_s *)self; + + if( !b->generic.name ) { + return; + } + + if( b->generic.name && !b->shader ) { + b->shader = trap_R_RegisterShaderNoMip( b->generic.name ); + if( !b->shader && b->errorpic ) { + b->shader = trap_R_RegisterShaderNoMip( b->errorpic ); + } + } + + if( b->focuspic && !b->focusshader ) { + b->focusshader = trap_R_RegisterShaderNoMip( b->focuspic ); + } + + x = b->generic.x; + y = b->generic.y; + w = b->width; + h = b->height; + if( b->shader ) { + UI_DrawHandlePic( x, y, w, h, b->shader ); + } + + x = b->generic.x; + y = b->generic.y + b->height; + UI_FillRect( x, y, b->width, 28, colorBlack ); + + x += b->width / 2; + y += 4; + n = s_startserver.page * MAX_MAPSPERPAGE + b->generic.id - ID_PICTURES; + UI_DrawString( x, y, s_startserver.maplist[n], UI_CENTER|UI_SMALLFONT, color_orange ); + + x = b->generic.x; + y = b->generic.y; + w = b->width; + h = b->height + 28; + if( b->generic.flags & QMF_HIGHLIGHT ) { + UI_DrawHandlePic( x, y, w, h, b->focusshader ); + } +} + + +/* +================= +StartServer_MenuInit +================= +*/ +static void StartServer_MenuInit( void ) { + int i; + int x; + int y; + static char mapnamebuffer[64]; + + // zero set all our globals + memset( &s_startserver, 0 ,sizeof(startserver_t) ); + + StartServer_Cache(); + + s_startserver.menu.wrapAround = qtrue; + s_startserver.menu.fullscreen = qtrue; + + s_startserver.banner.generic.type = MTYPE_BTEXT; + s_startserver.banner.generic.x = 320; + s_startserver.banner.generic.y = 16; + s_startserver.banner.string = "GAME SERVER"; + s_startserver.banner.color = color_white; + s_startserver.banner.style = UI_CENTER; + + s_startserver.framel.generic.type = MTYPE_BITMAP; + s_startserver.framel.generic.name = GAMESERVER_FRAMEL; + s_startserver.framel.generic.flags = QMF_INACTIVE; + s_startserver.framel.generic.x = 0; + s_startserver.framel.generic.y = 78; + s_startserver.framel.width = 256; + s_startserver.framel.height = 329; + + s_startserver.framer.generic.type = MTYPE_BITMAP; + s_startserver.framer.generic.name = GAMESERVER_FRAMER; + s_startserver.framer.generic.flags = QMF_INACTIVE; + s_startserver.framer.generic.x = 376; + s_startserver.framer.generic.y = 76; + s_startserver.framer.width = 256; + s_startserver.framer.height = 334; + + s_startserver.gametype.generic.type = MTYPE_SPINCONTROL; + s_startserver.gametype.generic.name = "Game Type:"; + s_startserver.gametype.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_startserver.gametype.generic.callback = StartServer_GametypeEvent; + s_startserver.gametype.generic.id = ID_GAMETYPE; + s_startserver.gametype.generic.x = 320 - 24; + s_startserver.gametype.generic.y = 368; + s_startserver.gametype.itemnames = gametype_items; + + for (i=0; i= GT_TEAM) && + (s_serveroptions.playerTeam[n].curvalue != s_serveroptions.playerTeam[s_serveroptions.newBotIndex].curvalue ) ) { + continue; + } + if( Q_stricmp( checkName, s_serveroptions.playerNameBuffers[n] ) == 0 ) { + return qtrue; + } + } + + return qfalse; +} + + +/* +================= +ServerOptions_Start +================= +*/ +static void ServerOptions_Start( void ) { + int timelimit; + int fraglimit; + int maxclients; + int dedicated; + int friendlyfire; + int flaglimit; + int pure; + int skill; + int n; + char buf[64]; + + + timelimit = atoi( s_serveroptions.timelimit.field.buffer ); + fraglimit = atoi( s_serveroptions.fraglimit.field.buffer ); + flaglimit = atoi( s_serveroptions.flaglimit.field.buffer ); + dedicated = s_serveroptions.dedicated.curvalue; + friendlyfire = s_serveroptions.friendlyfire.curvalue; + pure = s_serveroptions.pure.curvalue; + skill = s_serveroptions.botSkill.curvalue + 1; + + //set maxclients + for( n = 0, maxclients = 0; n < PLAYER_SLOTS; n++ ) { + if( s_serveroptions.playerType[n].curvalue == 2 ) { + continue; + } + if( (s_serveroptions.playerType[n].curvalue == 1) && (s_serveroptions.playerNameBuffers[n][0] == 0) ) { + continue; + } + maxclients++; + } + + switch( s_serveroptions.gametype ) { + case GT_FFA: + default: + trap_Cvar_SetValue( "ui_ffa_fraglimit", fraglimit ); + trap_Cvar_SetValue( "ui_ffa_timelimit", timelimit ); + break; + + case GT_TOURNAMENT: + trap_Cvar_SetValue( "ui_tourney_fraglimit", fraglimit ); + trap_Cvar_SetValue( "ui_tourney_timelimit", timelimit ); + break; + + case GT_TEAM: + trap_Cvar_SetValue( "ui_team_fraglimit", fraglimit ); + trap_Cvar_SetValue( "ui_team_timelimit", timelimit ); + trap_Cvar_SetValue( "ui_team_friendlt", friendlyfire ); + break; + + case GT_CTF: + trap_Cvar_SetValue( "ui_ctf_fraglimit", fraglimit ); + trap_Cvar_SetValue( "ui_ctf_timelimit", timelimit ); + trap_Cvar_SetValue( "ui_ctf_friendlt", friendlyfire ); + break; + } + + trap_Cvar_SetValue( "sv_maxclients", Com_Clamp( 0, 12, maxclients ) ); + trap_Cvar_SetValue( "dedicated", Com_Clamp( 0, 2, dedicated ) ); + trap_Cvar_SetValue ("timelimit", Com_Clamp( 0, timelimit, timelimit ) ); + trap_Cvar_SetValue ("fraglimit", Com_Clamp( 0, fraglimit, fraglimit ) ); + trap_Cvar_SetValue ("capturelimit", Com_Clamp( 0, flaglimit, flaglimit ) ); + trap_Cvar_SetValue( "g_friendlyfire", friendlyfire ); + trap_Cvar_SetValue( "sv_pure", pure ); + trap_Cvar_Set("sv_hostname", s_serveroptions.hostname.field.buffer ); + + trap_Cvar_SetValue( "sv_punkbuster", s_serveroptions.punkbuster.curvalue ); + + // the wait commands will allow the dedicated to take effect + trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", s_startserver.maplist[s_startserver.currentmap] ) ); + + // add bots + trap_Cmd_ExecuteText( EXEC_APPEND, "wait 3\n" ); + for( n = 1; n < PLAYER_SLOTS; n++ ) { + if( s_serveroptions.playerType[n].curvalue != 1 ) { + continue; + } + if( s_serveroptions.playerNameBuffers[n][0] == 0 ) { + continue; + } + if( s_serveroptions.playerNameBuffers[n][0] == '-' ) { + continue; + } + if( s_serveroptions.gametype >= GT_TEAM ) { + Com_sprintf( buf, sizeof(buf), "addbot %s %i %s\n", s_serveroptions.playerNameBuffers[n], skill, + playerTeam_list[s_serveroptions.playerTeam[n].curvalue] ); + } + else { + Com_sprintf( buf, sizeof(buf), "addbot %s %i\n", s_serveroptions.playerNameBuffers[n], skill ); + } + trap_Cmd_ExecuteText( EXEC_APPEND, buf ); + } + + // set player's team + if( dedicated == 0 && s_serveroptions.gametype >= GT_TEAM ) { + trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait 5; team %s\n", playerTeam_list[s_serveroptions.playerTeam[0].curvalue] ) ); + } +} + + +/* +================= +ServerOptions_InitPlayerItems +================= +*/ +static void ServerOptions_InitPlayerItems( void ) { + int n; + int v; + + // init types + if( s_serveroptions.multiplayer ) { + v = 0; // open + } + else { + v = 1; // bot + } + + for( n = 0; n < PLAYER_SLOTS; n++ ) { + s_serveroptions.playerType[n].curvalue = v; + } + + if( s_serveroptions.multiplayer && (s_serveroptions.gametype < GT_TEAM) ) { + for( n = 8; n < PLAYER_SLOTS; n++ ) { + s_serveroptions.playerType[n].curvalue = 2; + } + } + + // if not a dedicated server, first slot is reserved for the human on the server + if( s_serveroptions.dedicated.curvalue == 0 ) { + // human + s_serveroptions.playerType[0].generic.flags |= QMF_INACTIVE; + s_serveroptions.playerType[0].curvalue = 0; + trap_Cvar_VariableStringBuffer( "name", s_serveroptions.playerNameBuffers[0], sizeof(s_serveroptions.playerNameBuffers[0]) ); + Q_CleanStr( s_serveroptions.playerNameBuffers[0] ); + } + + // init teams + if( s_serveroptions.gametype >= GT_TEAM ) { + for( n = 0; n < (PLAYER_SLOTS / 2); n++ ) { + s_serveroptions.playerTeam[n].curvalue = 0; + } + for( ; n < PLAYER_SLOTS; n++ ) { + s_serveroptions.playerTeam[n].curvalue = 1; + } + } + else { + for( n = 0; n < PLAYER_SLOTS; n++ ) { + s_serveroptions.playerTeam[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); + } + } +} + + +/* +================= +ServerOptions_SetPlayerItems +================= +*/ +static void ServerOptions_SetPlayerItems( void ) { + int start; + int n; + + // types +// for( n = 0; n < PLAYER_SLOTS; n++ ) { +// if( (!s_serveroptions.multiplayer) && (n > 0) && (s_serveroptions.playerType[n].curvalue == 0) ) { +// s_serveroptions.playerType[n].curvalue = 1; +// } +// } + + // names + if( s_serveroptions.dedicated.curvalue == 0 ) { + s_serveroptions.player0.string = "Human"; + s_serveroptions.playerName[0].generic.flags &= ~QMF_HIDDEN; + + start = 1; + } + else { + s_serveroptions.player0.string = "Open"; + start = 0; + } + for( n = start; n < PLAYER_SLOTS; n++ ) { + if( s_serveroptions.playerType[n].curvalue == 1 ) { + s_serveroptions.playerName[n].generic.flags &= ~(QMF_INACTIVE|QMF_HIDDEN); + } + else { + s_serveroptions.playerName[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); + } + } + + // teams + if( s_serveroptions.gametype < GT_TEAM ) { + return; + } + for( n = start; n < PLAYER_SLOTS; n++ ) { + if( s_serveroptions.playerType[n].curvalue == 2 ) { + s_serveroptions.playerTeam[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); + } + else { + s_serveroptions.playerTeam[n].generic.flags &= ~(QMF_INACTIVE|QMF_HIDDEN); + } + } +} + + +/* +================= +ServerOptions_Event +================= +*/ +static void ServerOptions_Event( void* ptr, int event ) { + switch( ((menucommon_s*)ptr)->id ) { + + //if( event != QM_ACTIVATED && event != QM_LOSTFOCUS) { + // return; + //} + case ID_PLAYER_TYPE: + if( event != QM_ACTIVATED ) { + break; + } + ServerOptions_SetPlayerItems(); + break; + + case ID_MAXCLIENTS: + case ID_DEDICATED: + ServerOptions_SetPlayerItems(); + break; + case ID_GO: + if( event != QM_ACTIVATED ) { + break; + } + ServerOptions_Start(); + break; + + case ID_STARTSERVERNEXT: + if( event != QM_ACTIVATED ) { + break; + } + break; + case ID_BACK: + if( event != QM_ACTIVATED ) { + break; + } + UI_PopMenu(); + break; + } +} + + +static void ServerOptions_PlayerNameEvent( void* ptr, int event ) { + int n; + + if( event != QM_ACTIVATED ) { + return; + } + n = ((menutext_s*)ptr)->generic.id; + s_serveroptions.newBotIndex = n; + UI_BotSelectMenu( s_serveroptions.playerNameBuffers[n] ); +} + + +/* +================= +ServerOptions_StatusBar +================= +*/ +static void ServerOptions_StatusBar( void* ptr ) { + switch( ((menucommon_s*)ptr)->id ) { + default: + UI_DrawString( 320, 440, "0 = NO LIMIT", UI_CENTER|UI_SMALLFONT, colorWhite ); + break; + } +} + + +/* +=============== +ServerOptions_LevelshotDraw +=============== +*/ +static void ServerOptions_LevelshotDraw( void *self ) { + menubitmap_s *b; + int x; + int y; + + // strange place for this, but it works + if( s_serveroptions.newBot ) { + Q_strncpyz( s_serveroptions.playerNameBuffers[s_serveroptions.newBotIndex], s_serveroptions.newBotName, 16 ); + s_serveroptions.newBot = qfalse; + } + + b = (menubitmap_s *)self; + + Bitmap_Draw( b ); + + x = b->generic.x; + y = b->generic.y + b->height; + UI_FillRect( x, y, b->width, 40, colorBlack ); + + x += b->width / 2; + y += 4; + UI_DrawString( x, y, s_serveroptions.mapnamebuffer, UI_CENTER|UI_SMALLFONT, color_orange ); + + y += SMALLCHAR_HEIGHT; + UI_DrawString( x, y, gametype_items[gametype_remap2[s_serveroptions.gametype]], UI_CENTER|UI_SMALLFONT, color_orange ); +} + + +static void ServerOptions_InitBotNames( void ) { + int count; + int n; + const char *arenaInfo; + const char *botInfo; + char *p; + char *bot; + char bots[MAX_INFO_STRING]; + + if( s_serveroptions.gametype >= GT_TEAM ) { + Q_strncpyz( s_serveroptions.playerNameBuffers[1], "grunt", 16 ); + Q_strncpyz( s_serveroptions.playerNameBuffers[2], "major", 16 ); + if( s_serveroptions.gametype == GT_TEAM ) { + Q_strncpyz( s_serveroptions.playerNameBuffers[3], "visor", 16 ); + } + else { + s_serveroptions.playerType[3].curvalue = 2; + } + s_serveroptions.playerType[4].curvalue = 2; + s_serveroptions.playerType[5].curvalue = 2; + + Q_strncpyz( s_serveroptions.playerNameBuffers[6], "sarge", 16 ); + Q_strncpyz( s_serveroptions.playerNameBuffers[7], "grunt", 16 ); + Q_strncpyz( s_serveroptions.playerNameBuffers[8], "major", 16 ); + if( s_serveroptions.gametype == GT_TEAM ) { + Q_strncpyz( s_serveroptions.playerNameBuffers[9], "visor", 16 ); + } + else { + s_serveroptions.playerType[9].curvalue = 2; + } + s_serveroptions.playerType[10].curvalue = 2; + s_serveroptions.playerType[11].curvalue = 2; + + return; + } + + count = 1; // skip the first slot, reserved for a human + + // get info for this map + arenaInfo = UI_GetArenaInfoByMap( s_serveroptions.mapnamebuffer ); + + // get the bot info - we'll seed with them if any are listed + Q_strncpyz( bots, Info_ValueForKey( arenaInfo, "bots" ), sizeof(bots) ); + p = &bots[0]; + while( *p && count < PLAYER_SLOTS ) { + //skip spaces + while( *p && *p == ' ' ) { + p++; + } + if( !p ) { + break; + } + + // mark start of bot name + bot = p; + + // skip until space of null + while( *p && *p != ' ' ) { + p++; + } + if( *p ) { + *p++ = 0; + } + + botInfo = UI_GetBotInfoByName( bot ); + bot = Info_ValueForKey( botInfo, "name" ); + + Q_strncpyz( s_serveroptions.playerNameBuffers[count], bot, sizeof(s_serveroptions.playerNameBuffers[count]) ); + count++; + } + + // set the rest of the bot slots to "---" + for( n = count; n < PLAYER_SLOTS; n++ ) { + strcpy( s_serveroptions.playerNameBuffers[n], "--------" ); + } + + // pad up to #8 as open slots + for( ;count < 8; count++ ) { + s_serveroptions.playerType[count].curvalue = 0; + } + + // close off the rest by default + for( ;count < PLAYER_SLOTS; count++ ) { + if( s_serveroptions.playerType[count].curvalue == 1 ) { + s_serveroptions.playerType[count].curvalue = 2; + } + } +} + + +/* +================= +ServerOptions_SetMenuItems +================= +*/ +static void ServerOptions_SetMenuItems( void ) { + static char picname[64]; + + switch( s_serveroptions.gametype ) { + case GT_FFA: + default: + Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ffa_fraglimit" ) ) ); + Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ffa_timelimit" ) ) ); + break; + + case GT_TOURNAMENT: + Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_tourney_fraglimit" ) ) ); + Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_tourney_timelimit" ) ) ); + break; + + case GT_TEAM: + Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_team_fraglimit" ) ) ); + Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_team_timelimit" ) ) ); + s_serveroptions.friendlyfire.curvalue = (int)Com_Clamp( 0, 1, trap_Cvar_VariableValue( "ui_team_friendly" ) ); + break; + + case GT_CTF: + Com_sprintf( s_serveroptions.flaglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 100, trap_Cvar_VariableValue( "ui_ctf_capturelimit" ) ) ); + Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ctf_timelimit" ) ) ); + s_serveroptions.friendlyfire.curvalue = (int)Com_Clamp( 0, 1, trap_Cvar_VariableValue( "ui_ctf_friendly" ) ); + break; + } + + Q_strncpyz( s_serveroptions.hostname.field.buffer, UI_Cvar_VariableString( "sv_hostname" ), sizeof( s_serveroptions.hostname.field.buffer ) ); + s_serveroptions.pure.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "sv_pure" ) ); + + // set the map pic + Com_sprintf( picname, 64, "levelshots/%s", s_startserver.maplist[s_startserver.currentmap] ); + s_serveroptions.mappic.generic.name = picname; + + // set the map name + strcpy( s_serveroptions.mapnamebuffer, s_startserver.mapname.string ); + Q_strupr( s_serveroptions.mapnamebuffer ); + + // get the player selections initialized + ServerOptions_InitPlayerItems(); + ServerOptions_SetPlayerItems(); + + // seed bot names + ServerOptions_InitBotNames(); + ServerOptions_SetPlayerItems(); +} + +/* +================= +PlayerName_Draw +================= +*/ +static void PlayerName_Draw( void *item ) { + menutext_s *s; + float *color; + int x, y; + int style; + qboolean focus; + + s = (menutext_s *)item; + + x = s->generic.x; + y = s->generic.y; + + style = UI_SMALLFONT; + focus = (s->generic.parent->cursor == s->generic.menuPosition); + + if ( s->generic.flags & QMF_GRAYED ) + color = text_color_disabled; + else if ( focus ) + { + color = text_color_highlight; + style |= UI_PULSE; + } + else if ( s->generic.flags & QMF_BLINK ) + { + color = text_color_highlight; + style |= UI_BLINK; + } + else + color = text_color_normal; + + if ( focus ) + { + // draw cursor + UI_FillRect( s->generic.left, s->generic.top, s->generic.right-s->generic.left+1, s->generic.bottom-s->generic.top+1, listbar_color ); + UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); + } + + UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, style|UI_RIGHT, color ); + UI_DrawString( x + SMALLCHAR_WIDTH, y, s->string, style|UI_LEFT, color ); +} + + +/* +================= +ServerOptions_MenuInit +================= +*/ +#define OPTIONS_X 456 + +static void ServerOptions_MenuInit( qboolean multiplayer ) { + int y; + int n; + + memset( &s_serveroptions, 0 ,sizeof(serveroptions_t) ); + s_serveroptions.multiplayer = multiplayer; + s_serveroptions.gametype = (int)Com_Clamp( 0, 5, trap_Cvar_VariableValue( "g_gameType" ) ); + s_serveroptions.punkbuster.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "sv_punkbuster" ) ); + + ServerOptions_Cache(); + + s_serveroptions.menu.wrapAround = qtrue; + s_serveroptions.menu.fullscreen = qtrue; + + s_serveroptions.banner.generic.type = MTYPE_BTEXT; + s_serveroptions.banner.generic.x = 320; + s_serveroptions.banner.generic.y = 16; + s_serveroptions.banner.string = "GAME SERVER"; + s_serveroptions.banner.color = color_white; + s_serveroptions.banner.style = UI_CENTER; + + s_serveroptions.mappic.generic.type = MTYPE_BITMAP; + s_serveroptions.mappic.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + s_serveroptions.mappic.generic.x = 352; + s_serveroptions.mappic.generic.y = 80; + s_serveroptions.mappic.width = 160; + s_serveroptions.mappic.height = 120; + s_serveroptions.mappic.errorpic = GAMESERVER_UNKNOWNMAP; + s_serveroptions.mappic.generic.ownerdraw = ServerOptions_LevelshotDraw; + + s_serveroptions.picframe.generic.type = MTYPE_BITMAP; + s_serveroptions.picframe.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE|QMF_HIGHLIGHT; + s_serveroptions.picframe.generic.x = 352 - 38; + s_serveroptions.picframe.generic.y = 80 - 40; + s_serveroptions.picframe.width = 320; + s_serveroptions.picframe.height = 320; + s_serveroptions.picframe.focuspic = GAMESERVER_SELECT; + + y = 272; + if( s_serveroptions.gametype != GT_CTF ) { + s_serveroptions.fraglimit.generic.type = MTYPE_FIELD; + s_serveroptions.fraglimit.generic.name = "Frag Limit:"; + s_serveroptions.fraglimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.fraglimit.generic.x = OPTIONS_X; + s_serveroptions.fraglimit.generic.y = y; + s_serveroptions.fraglimit.generic.statusbar = ServerOptions_StatusBar; + s_serveroptions.fraglimit.field.widthInChars = 3; + s_serveroptions.fraglimit.field.maxchars = 3; + } + else { + s_serveroptions.flaglimit.generic.type = MTYPE_FIELD; + s_serveroptions.flaglimit.generic.name = "Capture Limit:"; + s_serveroptions.flaglimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.flaglimit.generic.x = OPTIONS_X; + s_serveroptions.flaglimit.generic.y = y; + s_serveroptions.flaglimit.generic.statusbar = ServerOptions_StatusBar; + s_serveroptions.flaglimit.field.widthInChars = 3; + s_serveroptions.flaglimit.field.maxchars = 3; + } + + y += BIGCHAR_HEIGHT+2; + s_serveroptions.timelimit.generic.type = MTYPE_FIELD; + s_serveroptions.timelimit.generic.name = "Time Limit:"; + s_serveroptions.timelimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.timelimit.generic.x = OPTIONS_X; + s_serveroptions.timelimit.generic.y = y; + s_serveroptions.timelimit.generic.statusbar = ServerOptions_StatusBar; + s_serveroptions.timelimit.field.widthInChars = 3; + s_serveroptions.timelimit.field.maxchars = 3; + + if( s_serveroptions.gametype >= GT_TEAM ) { + y += BIGCHAR_HEIGHT+2; + s_serveroptions.friendlyfire.generic.type = MTYPE_RADIOBUTTON; + s_serveroptions.friendlyfire.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.friendlyfire.generic.x = OPTIONS_X; + s_serveroptions.friendlyfire.generic.y = y; + s_serveroptions.friendlyfire.generic.name = "Friendly Fire:"; + } + + y += BIGCHAR_HEIGHT+2; + s_serveroptions.pure.generic.type = MTYPE_RADIOBUTTON; + s_serveroptions.pure.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.pure.generic.x = OPTIONS_X; + s_serveroptions.pure.generic.y = y; + s_serveroptions.pure.generic.name = "Pure Server:"; + + if( s_serveroptions.multiplayer ) { + y += BIGCHAR_HEIGHT+2; + s_serveroptions.dedicated.generic.type = MTYPE_SPINCONTROL; + s_serveroptions.dedicated.generic.id = ID_DEDICATED; + s_serveroptions.dedicated.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.dedicated.generic.callback = ServerOptions_Event; + s_serveroptions.dedicated.generic.x = OPTIONS_X; + s_serveroptions.dedicated.generic.y = y; + s_serveroptions.dedicated.generic.name = "Dedicated:"; + s_serveroptions.dedicated.itemnames = dedicated_list; + } + + if( s_serveroptions.multiplayer ) { + y += BIGCHAR_HEIGHT+2; + s_serveroptions.hostname.generic.type = MTYPE_FIELD; + s_serveroptions.hostname.generic.name = "Hostname:"; + s_serveroptions.hostname.generic.flags = QMF_SMALLFONT; + s_serveroptions.hostname.generic.x = OPTIONS_X; + s_serveroptions.hostname.generic.y = y; + s_serveroptions.hostname.field.widthInChars = 18; + s_serveroptions.hostname.field.maxchars = 64; + } + + y += BIGCHAR_HEIGHT+2; + s_serveroptions.punkbuster.generic.type = MTYPE_SPINCONTROL; + s_serveroptions.punkbuster.generic.name = "Punkbuster:"; + s_serveroptions.punkbuster.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.punkbuster.generic.id = 0; + s_serveroptions.punkbuster.generic.x = OPTIONS_X; + s_serveroptions.punkbuster.generic.y = y; + s_serveroptions.punkbuster.itemnames = punkbuster_items; + + y = 80; + s_serveroptions.botSkill.generic.type = MTYPE_SPINCONTROL; + s_serveroptions.botSkill.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.botSkill.generic.name = "Bot Skill: "; + s_serveroptions.botSkill.generic.x = 32 + (strlen(s_serveroptions.botSkill.generic.name) + 2 ) * SMALLCHAR_WIDTH; + s_serveroptions.botSkill.generic.y = y; + s_serveroptions.botSkill.itemnames = botSkill_list; + s_serveroptions.botSkill.curvalue = 1; + + y += ( 2 * SMALLCHAR_HEIGHT ); + s_serveroptions.player0.generic.type = MTYPE_TEXT; + s_serveroptions.player0.generic.flags = QMF_SMALLFONT; + s_serveroptions.player0.generic.x = 32 + SMALLCHAR_WIDTH; + s_serveroptions.player0.generic.y = y; + s_serveroptions.player0.color = color_orange; + s_serveroptions.player0.style = UI_LEFT|UI_SMALLFONT; + + for( n = 0; n < PLAYER_SLOTS; n++ ) { + s_serveroptions.playerType[n].generic.type = MTYPE_SPINCONTROL; + s_serveroptions.playerType[n].generic.flags = QMF_SMALLFONT; + s_serveroptions.playerType[n].generic.id = ID_PLAYER_TYPE; + s_serveroptions.playerType[n].generic.callback = ServerOptions_Event; + s_serveroptions.playerType[n].generic.x = 32; + s_serveroptions.playerType[n].generic.y = y; + s_serveroptions.playerType[n].itemnames = playerType_list; + + s_serveroptions.playerName[n].generic.type = MTYPE_TEXT; + s_serveroptions.playerName[n].generic.flags = QMF_SMALLFONT; + s_serveroptions.playerName[n].generic.x = 96; + s_serveroptions.playerName[n].generic.y = y; + s_serveroptions.playerName[n].generic.callback = ServerOptions_PlayerNameEvent; + s_serveroptions.playerName[n].generic.id = n; + s_serveroptions.playerName[n].generic.ownerdraw = PlayerName_Draw; + s_serveroptions.playerName[n].color = color_orange; + s_serveroptions.playerName[n].style = UI_SMALLFONT; + s_serveroptions.playerName[n].string = s_serveroptions.playerNameBuffers[n]; + s_serveroptions.playerName[n].generic.top = s_serveroptions.playerName[n].generic.y; + s_serveroptions.playerName[n].generic.bottom = s_serveroptions.playerName[n].generic.y + SMALLCHAR_HEIGHT; + s_serveroptions.playerName[n].generic.left = s_serveroptions.playerName[n].generic.x - SMALLCHAR_HEIGHT/ 2; + s_serveroptions.playerName[n].generic.right = s_serveroptions.playerName[n].generic.x + 16 * SMALLCHAR_WIDTH; + + s_serveroptions.playerTeam[n].generic.type = MTYPE_SPINCONTROL; + s_serveroptions.playerTeam[n].generic.flags = QMF_SMALLFONT; + s_serveroptions.playerTeam[n].generic.x = 240; + s_serveroptions.playerTeam[n].generic.y = y; + s_serveroptions.playerTeam[n].itemnames = playerTeam_list; + + y += ( SMALLCHAR_HEIGHT + 4 ); + } + + s_serveroptions.back.generic.type = MTYPE_BITMAP; + s_serveroptions.back.generic.name = GAMESERVER_BACK0; + s_serveroptions.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_serveroptions.back.generic.callback = ServerOptions_Event; + s_serveroptions.back.generic.id = ID_BACK; + s_serveroptions.back.generic.x = 0; + s_serveroptions.back.generic.y = 480-64; + s_serveroptions.back.width = 128; + s_serveroptions.back.height = 64; + s_serveroptions.back.focuspic = GAMESERVER_BACK1; + + s_serveroptions.next.generic.type = MTYPE_BITMAP; + s_serveroptions.next.generic.name = GAMESERVER_NEXT0; + s_serveroptions.next.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE|QMF_GRAYED|QMF_HIDDEN; + s_serveroptions.next.generic.callback = ServerOptions_Event; + s_serveroptions.next.generic.id = ID_STARTSERVERNEXT; + s_serveroptions.next.generic.x = 640; + s_serveroptions.next.generic.y = 480-64-72; + s_serveroptions.next.generic.statusbar = ServerOptions_StatusBar; + s_serveroptions.next.width = 128; + s_serveroptions.next.height = 64; + s_serveroptions.next.focuspic = GAMESERVER_NEXT1; + + s_serveroptions.go.generic.type = MTYPE_BITMAP; + s_serveroptions.go.generic.name = GAMESERVER_FIGHT0; + s_serveroptions.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_serveroptions.go.generic.callback = ServerOptions_Event; + s_serveroptions.go.generic.id = ID_GO; + s_serveroptions.go.generic.x = 640; + s_serveroptions.go.generic.y = 480-64; + s_serveroptions.go.width = 128; + s_serveroptions.go.height = 64; + s_serveroptions.go.focuspic = GAMESERVER_FIGHT1; + + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.banner ); + + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.mappic ); + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.picframe ); + + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.botSkill ); + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.player0 ); + for( n = 0; n < PLAYER_SLOTS; n++ ) { + if( n != 0 ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerType[n] ); + } + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerName[n] ); + if( s_serveroptions.gametype >= GT_TEAM ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerTeam[n] ); + } + } + + if( s_serveroptions.gametype != GT_CTF ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.fraglimit ); + } + else { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.flaglimit ); + } + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.timelimit ); + if( s_serveroptions.gametype >= GT_TEAM ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.friendlyfire ); + } + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.pure ); + if( s_serveroptions.multiplayer ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.dedicated ); + } + if( s_serveroptions.multiplayer ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.hostname ); + } + + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.back ); + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.next ); + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.go ); + + Menu_AddItem( &s_serveroptions.menu, (void*) &s_serveroptions.punkbuster ); + + ServerOptions_SetMenuItems(); +} + +/* +================= +ServerOptions_Cache +================= +*/ +void ServerOptions_Cache( void ) { + trap_R_RegisterShaderNoMip( GAMESERVER_BACK0 ); + trap_R_RegisterShaderNoMip( GAMESERVER_BACK1 ); + trap_R_RegisterShaderNoMip( GAMESERVER_FIGHT0 ); + trap_R_RegisterShaderNoMip( GAMESERVER_FIGHT1 ); + trap_R_RegisterShaderNoMip( GAMESERVER_SELECT ); + trap_R_RegisterShaderNoMip( GAMESERVER_UNKNOWNMAP ); +} + + +/* +================= +UI_ServerOptionsMenu +================= +*/ +static void UI_ServerOptionsMenu( qboolean multiplayer ) { + ServerOptions_MenuInit( multiplayer ); + UI_PushMenu( &s_serveroptions.menu ); +} + + + +/* +============================================================================= + +BOT SELECT MENU ***** + +============================================================================= +*/ + + +#define BOTSELECT_BACK0 "menu/art/back_0" +#define BOTSELECT_BACK1 "menu/art/back_1" +#define BOTSELECT_ACCEPT0 "menu/art/accept_0" +#define BOTSELECT_ACCEPT1 "menu/art/accept_1" +#define BOTSELECT_SELECT "menu/art/opponents_select" +#define BOTSELECT_SELECTED "menu/art/opponents_selected" +#define BOTSELECT_ARROWS "menu/art/gs_arrows_0" +#define BOTSELECT_ARROWSL "menu/art/gs_arrows_l" +#define BOTSELECT_ARROWSR "menu/art/gs_arrows_r" + +#define PLAYERGRID_COLS 4 +#define PLAYERGRID_ROWS 4 +#define MAX_MODELSPERPAGE (PLAYERGRID_ROWS * PLAYERGRID_COLS) + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + + menubitmap_s pics[MAX_MODELSPERPAGE]; + menubitmap_s picbuttons[MAX_MODELSPERPAGE]; + menutext_s picnames[MAX_MODELSPERPAGE]; + + menubitmap_s arrows; + menubitmap_s left; + menubitmap_s right; + + menubitmap_s go; + menubitmap_s back; + + int numBots; + int modelpage; + int numpages; + int selectedmodel; + int sortedBotNums[MAX_BOTS]; + char boticons[MAX_MODELSPERPAGE][MAX_QPATH]; + char botnames[MAX_MODELSPERPAGE][16]; +} botSelectInfo_t; + +static botSelectInfo_t botSelectInfo; + + +/* +================= +UI_BotSelectMenu_SortCompare +================= +*/ +static int QDECL UI_BotSelectMenu_SortCompare( const void *arg1, const void *arg2 ) { + int num1, num2; + const char *info1, *info2; + const char *name1, *name2; + + num1 = *(int *)arg1; + num2 = *(int *)arg2; + + info1 = UI_GetBotInfoByNumber( num1 ); + info2 = UI_GetBotInfoByNumber( num2 ); + + name1 = Info_ValueForKey( info1, "name" ); + name2 = Info_ValueForKey( info2, "name" ); + + return Q_stricmp( name1, name2 ); +} + + +/* +================= +UI_BotSelectMenu_BuildList +================= +*/ +static void UI_BotSelectMenu_BuildList( void ) { + int n; + + botSelectInfo.modelpage = 0; + botSelectInfo.numBots = UI_GetNumBots(); + botSelectInfo.numpages = botSelectInfo.numBots / MAX_MODELSPERPAGE; + if( botSelectInfo.numBots % MAX_MODELSPERPAGE ) { + botSelectInfo.numpages++; + } + + // initialize the array + for( n = 0; n < botSelectInfo.numBots; n++ ) { + botSelectInfo.sortedBotNums[n] = n; + } + + // now sort it + qsort( botSelectInfo.sortedBotNums, botSelectInfo.numBots, sizeof(botSelectInfo.sortedBotNums[0]), UI_BotSelectMenu_SortCompare ); +} + + +/* +================= +ServerPlayerIcon +================= +*/ +static void ServerPlayerIcon( const char *modelAndSkin, char *iconName, int iconNameMaxSize ) { + char *skin; + char model[MAX_QPATH]; + + Q_strncpyz( model, modelAndSkin, sizeof(model)); + skin = Q_strrchr( model, '/' ); + if ( skin ) { + *skin++ = '\0'; + } + else { + skin = "default"; + } + + Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_%s.tga", model, skin ); + + if( !trap_R_RegisterShaderNoMip( iconName ) && Q_stricmp( skin, "default" ) != 0 ) { + Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_default.tga", model ); + } +} + + +/* +================= +UI_BotSelectMenu_UpdateGrid +================= +*/ +static void UI_BotSelectMenu_UpdateGrid( void ) { + const char *info; + int i; + int j; + + j = botSelectInfo.modelpage * MAX_MODELSPERPAGE; + for( i = 0; i < (PLAYERGRID_ROWS * PLAYERGRID_COLS); i++, j++) { + if( j < botSelectInfo.numBots ) { + info = UI_GetBotInfoByNumber( botSelectInfo.sortedBotNums[j] ); + ServerPlayerIcon( Info_ValueForKey( info, "model" ), botSelectInfo.boticons[i], MAX_QPATH ); + Q_strncpyz( botSelectInfo.botnames[i], Info_ValueForKey( info, "name" ), 16 ); + Q_CleanStr( botSelectInfo.botnames[i] ); + botSelectInfo.pics[i].generic.name = botSelectInfo.boticons[i]; + if( BotAlreadySelected( botSelectInfo.botnames[i] ) ) { + botSelectInfo.picnames[i].color = color_red; + } + else { + botSelectInfo.picnames[i].color = color_orange; + } + botSelectInfo.picbuttons[i].generic.flags &= ~QMF_INACTIVE; + } + else { + // dead slot + botSelectInfo.pics[i].generic.name = NULL; + botSelectInfo.picbuttons[i].generic.flags |= QMF_INACTIVE; + botSelectInfo.botnames[i][0] = 0; + } + + botSelectInfo.pics[i].generic.flags &= ~QMF_HIGHLIGHT; + botSelectInfo.pics[i].shader = 0; + botSelectInfo.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; + } + + // set selected model + i = botSelectInfo.selectedmodel % MAX_MODELSPERPAGE; + botSelectInfo.pics[i].generic.flags |= QMF_HIGHLIGHT; + botSelectInfo.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; + + if( botSelectInfo.numpages > 1 ) { + if( botSelectInfo.modelpage > 0 ) { + botSelectInfo.left.generic.flags &= ~QMF_INACTIVE; + } + else { + botSelectInfo.left.generic.flags |= QMF_INACTIVE; + } + + if( botSelectInfo.modelpage < (botSelectInfo.numpages - 1) ) { + botSelectInfo.right.generic.flags &= ~QMF_INACTIVE; + } + else { + botSelectInfo.right.generic.flags |= QMF_INACTIVE; + } + } + else { + // hide left/right markers + botSelectInfo.left.generic.flags |= QMF_INACTIVE; + botSelectInfo.right.generic.flags |= QMF_INACTIVE; + } +} + + +/* +================= +UI_BotSelectMenu_Default +================= +*/ +static void UI_BotSelectMenu_Default( char *bot ) { + const char *botInfo; + const char *test; + int n; + int i; + + for( n = 0; n < botSelectInfo.numBots; n++ ) { + botInfo = UI_GetBotInfoByNumber( n ); + test = Info_ValueForKey( botInfo, "name" ); + if( Q_stricmp( bot, test ) == 0 ) { + break; + } + } + if( n == botSelectInfo.numBots ) { + botSelectInfo.selectedmodel = 0; + return; + } + + for( i = 0; i < botSelectInfo.numBots; i++ ) { + if( botSelectInfo.sortedBotNums[i] == n ) { + break; + } + } + if( i == botSelectInfo.numBots ) { + botSelectInfo.selectedmodel = 0; + return; + } + + botSelectInfo.selectedmodel = i; +} + + +/* +================= +UI_BotSelectMenu_LeftEvent +================= +*/ +static void UI_BotSelectMenu_LeftEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + if( botSelectInfo.modelpage > 0 ) { + botSelectInfo.modelpage--; + botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE; + UI_BotSelectMenu_UpdateGrid(); + } +} + + +/* +================= +UI_BotSelectMenu_RightEvent +================= +*/ +static void UI_BotSelectMenu_RightEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + if( botSelectInfo.modelpage < botSelectInfo.numpages - 1 ) { + botSelectInfo.modelpage++; + botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE; + UI_BotSelectMenu_UpdateGrid(); + } +} + + +/* +================= +UI_BotSelectMenu_BotEvent +================= +*/ +static void UI_BotSelectMenu_BotEvent( void* ptr, int event ) { + int i; + + if( event != QM_ACTIVATED ) { + return; + } + + for( i = 0; i < (PLAYERGRID_ROWS * PLAYERGRID_COLS); i++ ) { + botSelectInfo.pics[i].generic.flags &= ~QMF_HIGHLIGHT; + botSelectInfo.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; + } + + // set selected + i = ((menucommon_s*)ptr)->id; + botSelectInfo.pics[i].generic.flags |= QMF_HIGHLIGHT; + botSelectInfo.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; + botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE + i; +} + + +/* +================= +UI_BotSelectMenu_BackEvent +================= +*/ +static void UI_BotSelectMenu_BackEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + UI_PopMenu(); +} + + +/* +================= +UI_BotSelectMenu_SelectEvent +================= +*/ +static void UI_BotSelectMenu_SelectEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + UI_PopMenu(); + + s_serveroptions.newBot = qtrue; + Q_strncpyz( s_serveroptions.newBotName, botSelectInfo.botnames[botSelectInfo.selectedmodel % MAX_MODELSPERPAGE], 16 ); +} + + +/* +================= +UI_BotSelectMenu_Cache +================= +*/ +void UI_BotSelectMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( BOTSELECT_BACK0 ); + trap_R_RegisterShaderNoMip( BOTSELECT_BACK1 ); + trap_R_RegisterShaderNoMip( BOTSELECT_ACCEPT0 ); + trap_R_RegisterShaderNoMip( BOTSELECT_ACCEPT1 ); + trap_R_RegisterShaderNoMip( BOTSELECT_SELECT ); + trap_R_RegisterShaderNoMip( BOTSELECT_SELECTED ); + trap_R_RegisterShaderNoMip( BOTSELECT_ARROWS ); + trap_R_RegisterShaderNoMip( BOTSELECT_ARROWSL ); + trap_R_RegisterShaderNoMip( BOTSELECT_ARROWSR ); +} + + +static void UI_BotSelectMenu_Init( char *bot ) { + int i, j, k; + int x, y; + + memset( &botSelectInfo, 0 ,sizeof(botSelectInfo) ); + botSelectInfo.menu.wrapAround = qtrue; + botSelectInfo.menu.fullscreen = qtrue; + + UI_BotSelectMenu_Cache(); + + botSelectInfo.banner.generic.type = MTYPE_BTEXT; + botSelectInfo.banner.generic.x = 320; + botSelectInfo.banner.generic.y = 16; + botSelectInfo.banner.string = "SELECT BOT"; + botSelectInfo.banner.color = color_white; + botSelectInfo.banner.style = UI_CENTER; + + y = 80; + for( i = 0, k = 0; i < PLAYERGRID_ROWS; i++) { + x = 180; + for( j = 0; j < PLAYERGRID_COLS; j++, k++ ) { + botSelectInfo.pics[k].generic.type = MTYPE_BITMAP; + botSelectInfo.pics[k].generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + botSelectInfo.pics[k].generic.x = x; + botSelectInfo.pics[k].generic.y = y; + botSelectInfo.pics[k].generic.name = botSelectInfo.boticons[k]; + botSelectInfo.pics[k].width = 64; + botSelectInfo.pics[k].height = 64; + botSelectInfo.pics[k].focuspic = BOTSELECT_SELECTED; + botSelectInfo.pics[k].focuscolor = colorRed; + + botSelectInfo.picbuttons[k].generic.type = MTYPE_BITMAP; + botSelectInfo.picbuttons[k].generic.flags = QMF_LEFT_JUSTIFY|QMF_NODEFAULTINIT|QMF_PULSEIFFOCUS; + botSelectInfo.picbuttons[k].generic.callback = UI_BotSelectMenu_BotEvent; + botSelectInfo.picbuttons[k].generic.id = k; + botSelectInfo.picbuttons[k].generic.x = x - 16; + botSelectInfo.picbuttons[k].generic.y = y - 16; + botSelectInfo.picbuttons[k].generic.left = x; + botSelectInfo.picbuttons[k].generic.top = y; + botSelectInfo.picbuttons[k].generic.right = x + 64; + botSelectInfo.picbuttons[k].generic.bottom = y + 64; + botSelectInfo.picbuttons[k].width = 128; + botSelectInfo.picbuttons[k].height = 128; + botSelectInfo.picbuttons[k].focuspic = BOTSELECT_SELECT; + botSelectInfo.picbuttons[k].focuscolor = colorRed; + + botSelectInfo.picnames[k].generic.type = MTYPE_TEXT; + botSelectInfo.picnames[k].generic.flags = QMF_SMALLFONT; + botSelectInfo.picnames[k].generic.x = x + 32; + botSelectInfo.picnames[k].generic.y = y + 64; + botSelectInfo.picnames[k].string = botSelectInfo.botnames[k]; + botSelectInfo.picnames[k].color = color_orange; + botSelectInfo.picnames[k].style = UI_CENTER|UI_SMALLFONT; + + x += (64 + 6); + } + y += (64 + SMALLCHAR_HEIGHT + 6); + } + + botSelectInfo.arrows.generic.type = MTYPE_BITMAP; + botSelectInfo.arrows.generic.name = BOTSELECT_ARROWS; + botSelectInfo.arrows.generic.flags = QMF_INACTIVE; + botSelectInfo.arrows.generic.x = 260; + botSelectInfo.arrows.generic.y = 440; + botSelectInfo.arrows.width = 128; + botSelectInfo.arrows.height = 32; + + botSelectInfo.left.generic.type = MTYPE_BITMAP; + botSelectInfo.left.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + botSelectInfo.left.generic.callback = UI_BotSelectMenu_LeftEvent; + botSelectInfo.left.generic.x = 260; + botSelectInfo.left.generic.y = 440; + botSelectInfo.left.width = 64; + botSelectInfo.left.height = 32; + botSelectInfo.left.focuspic = BOTSELECT_ARROWSL; + + botSelectInfo.right.generic.type = MTYPE_BITMAP; + botSelectInfo.right.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + botSelectInfo.right.generic.callback = UI_BotSelectMenu_RightEvent; + botSelectInfo.right.generic.x = 321; + botSelectInfo.right.generic.y = 440; + botSelectInfo.right.width = 64; + botSelectInfo.right.height = 32; + botSelectInfo.right.focuspic = BOTSELECT_ARROWSR; + + botSelectInfo.back.generic.type = MTYPE_BITMAP; + botSelectInfo.back.generic.name = BOTSELECT_BACK0; + botSelectInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + botSelectInfo.back.generic.callback = UI_BotSelectMenu_BackEvent; + botSelectInfo.back.generic.x = 0; + botSelectInfo.back.generic.y = 480-64; + botSelectInfo.back.width = 128; + botSelectInfo.back.height = 64; + botSelectInfo.back.focuspic = BOTSELECT_BACK1; + + botSelectInfo.go.generic.type = MTYPE_BITMAP; + botSelectInfo.go.generic.name = BOTSELECT_ACCEPT0; + botSelectInfo.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + botSelectInfo.go.generic.callback = UI_BotSelectMenu_SelectEvent; + botSelectInfo.go.generic.x = 640; + botSelectInfo.go.generic.y = 480-64; + botSelectInfo.go.width = 128; + botSelectInfo.go.height = 64; + botSelectInfo.go.focuspic = BOTSELECT_ACCEPT1; + + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.banner ); + for( i = 0; i < MAX_MODELSPERPAGE; i++ ) { + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.pics[i] ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.picbuttons[i] ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.picnames[i] ); + } + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.arrows ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.left ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.right ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.back ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.go ); + + UI_BotSelectMenu_BuildList(); + UI_BotSelectMenu_Default( bot ); + botSelectInfo.modelpage = botSelectInfo.selectedmodel / MAX_MODELSPERPAGE; + UI_BotSelectMenu_UpdateGrid(); +} + + +/* +================= +UI_BotSelectMenu +================= +*/ +void UI_BotSelectMenu( char *bot ) { + UI_BotSelectMenu_Init( bot ); + UI_PushMenu( &botSelectInfo.menu ); +} -- cgit v1.2.3