📄 ui_startserver.c
字号:
/*
===========================================================================
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<MAX_MAPSPERPAGE; i++)
{
if (top+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<MAX_MAPSPERPAGE; i++)
{
s_startserver.mappics[i].generic.flags &= ~QMF_HIGHLIGHT;
s_startserver.mappics[i].generic.name = NULL;
s_startserver.mappics[i].shader = 0;
// disable
s_startserver.mapbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS;
s_startserver.mapbuttons[i].generic.flags |= QMF_INACTIVE;
}
// no servers to start
if( !s_startserver.nummaps ) {
s_startserver.next.generic.flags |= QMF_INACTIVE;
// set the map name
strcpy( s_startserver.mapname.string, "NO MAPS FOUND" );
}
else {
// set the highlight
s_startserver.next.generic.flags &= ~QMF_INACTIVE;
i = s_startserver.currentmap - top;
if ( 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<MAX_MAPSPERPAGE; i++)
{
x = (i % MAX_MAPCOLS) * (128+8) + 188;
y = (i / MAX_MAPROWS) * (128+8) + 96;
s_startserver.mappics[i].generic.type = MTYPE_BITMAP;
s_startserver.mappics[i].generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
s_startserver.mappics[i].generic.x = x;
s_startserver.mappics[i].generic.y = y;
s_startserver.mappics[i].generic.id = ID_PICTURES+i;
s_startserver.mappics[i].width = 128;
s_startserver.mappics[i].height = 96;
s_startserver.mappics[i].focuspic = GAMESERVER_SELECTED;
s_startserver.mappics[i].errorpic = GAMESERVER_UNKNOWNMAP;
s_startserver.mappics[i].generic.ownerdraw = StartServer_LevelshotDraw;
s_startserver.mapbuttons[i].generic.type = MTYPE_BITMAP;
s_startserver.mapbuttons[i].generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_NODEFAULTINIT;
s_startserver.mapbuttons[i].generic.id = ID_PICTURES+i;
s_startserver.mapbuttons[i].generic.callback = StartServer_MapEvent;
s_startserver.mapbuttons[i].generic.x = x - 30;
s_startserver.mapbuttons[i].generic.y = y - 32;
s_startserver.mapbuttons[i].width = 256;
s_startserver.mapbuttons[i].height = 248;
s_startserver.mapbuttons[i].generic.left = x;
s_startserver.mapbuttons[i].generic.top = y;
s_startserver.mapbuttons[i].generic.right = x + 128;
s_startserver.mapbuttons[i].generic.bottom = y + 128;
s_startserver.mapbuttons[i].focuspic = GAMESERVER_SELECT;
}
s_startserver.arrows.generic.type = MTYPE_BITMAP;
s_startserver.arrows.generic.name = GAMESERVER_ARROWS;
s_startserver.arrows.generic.flags = QMF_INACTIVE;
s_startserver.arrows.generic.x = 260;
s_startserver.arrows.generic.y = 400;
s_startserver.arrows.width = 128;
s_startserver.arrows.height = 32;
s_startserver.prevpage.generic.type = MTYPE_BITMAP;
s_startserver.prevpage.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
s_startserver.prevpage.generic.callback = StartServer_MenuEvent;
s_startserver.prevpage.generic.id = ID_PREVPAGE;
s_startserver.prevpage.generic.x = 260;
s_startserver.prevpage.generic.y = 400;
s_startserver.prevpage.width = 64;
s_startserver.prevpage.height = 32;
s_startserver.prevpage.focuspic = GAMESERVER_ARROWSL;
s_startserver.nextpage.generic.type = MTYPE_BITMAP;
s_startserver.nextpage.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
s_startserver.nextpage.generic.callback = StartServer_MenuEvent;
s_startserver.nextpage.generic.id = ID_NEXTPAGE;
s_startserver.nextpage.generic.x = 321;
s_startserver.nextpage.generic.y = 400;
s_startserver.nextpage.width = 64;
s_startserver.nextpage.height = 32;
s_startserver.nextpage.focuspic = GAMESERVER_ARROWSR;
s_startserver.mapname.generic.type = MTYPE_PTEXT;
s_startserver.mapname.generic.flags = QMF_CENTER_JUSTIFY|QMF_INACTIVE;
s_startserver.mapname.generic.x = 320;
s_startserver.mapname.generic.y = 440;
s_startserver.mapname.string = mapnamebuffer;
s_startserver.mapname.style = UI_CENTER|UI_BIGFONT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -