diff options
author | Andrey Nazarov <skuller@skuller.net> | 2008-05-08 13:21:30 +0000 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2008-05-08 13:21:30 +0000 |
commit | c42cbedd8019373228e260de2f422fb7a15f4156 (patch) | |
tree | 9b7f615784ad2f69f93097c3f673cb2004461e0e /source/ui_multiplayer.c | |
parent | 2abb37ac482ea1d47a516784c2f23538dcc18e5d (diff) |
Removed hardcoded menus in favor of scriptable ones.
Made UI module part of the client, removed all glue.
Added `pushmenu', `popmenu', 'forcemenuoff' commands.
Detect gzipped files by contents, not by *.gz extension (TODO).
Diffstat (limited to 'source/ui_multiplayer.c')
-rw-r--r-- | source/ui_multiplayer.c | 486 |
1 files changed, 238 insertions, 248 deletions
diff --git a/source/ui_multiplayer.c b/source/ui_multiplayer.c index 7139c66..cfdccfd 100644 --- a/source/ui_multiplayer.c +++ b/source/ui_multiplayer.c @@ -1,5 +1,5 @@ /* -Copyright (C) 2003-2006 Andrey Nazarov +Copyright (C) 2003-2008 Andrey Nazarov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -28,65 +28,64 @@ JOIN SERVER MENU ============================================================================= */ -#define ID_LIST 101 -#define MAX_STATUS_RULES 64 +#define MAX_STATUS_RULES 64 #define MAX_STATUS_SERVERS 64 typedef struct serverSlot_s { - qboolean valid; - char *rules[MAX_STATUS_RULES]; - int numRules; - char *players[MAX_STATUS_PLAYERS]; - int numPlayers; - char address[MAX_QPATH]; - char realAddress[MAX_QPATH]; + qboolean valid; + char *rules[MAX_STATUS_RULES]; + int numRules; + char *players[MAX_STATUS_PLAYERS]; + int numPlayers; + char address[MAX_QPATH]; + char realAddress[MAX_QPATH]; } serverSlot_t; typedef struct m_joinServer_s { - menuFrameWork_t menu; - menuList_t list; - menuList_t info; - menuList_t players; + menuFrameWork_t menu; + menuList_t list; + menuList_t info; + menuList_t players; qboolean active; qboolean cursorSet; - serverSlot_t servers[MAX_STATUS_SERVERS]; - char *names[MAX_STATUS_SERVERS]; + serverSlot_t servers[MAX_STATUS_SERVERS]; + char *names[MAX_STATUS_SERVERS]; } m_joinServer_t; -static m_joinServer_t m_join; +static m_joinServer_t m_join; static void UpdateSelection( void ) { - serverSlot_t *s = &m_join.servers[m_join.list.curvalue]; - - if( s->valid ) { - m_join.info.generic.flags &= ~QMF_HIDDEN; - m_join.info.items = ( void ** )s->rules; - m_join.info.numItems = s->numRules; - - if( s->numPlayers ) { - m_join.players.generic.flags &= ~QMF_HIDDEN; - m_join.players.items = ( void ** )s->players; - m_join.players.numItems = s->numPlayers; - } else { - m_join.players.generic.flags |= QMF_HIDDEN; - m_join.players.items = NULL; - m_join.players.numItems = 0; - } - - m_join.menu.statusbar = "Press Enter to connect; Space to refresh"; - } else { - m_join.info.generic.flags |= QMF_HIDDEN; - m_join.info.items = NULL; - m_join.info.numItems = 0; - - m_join.players.generic.flags |= QMF_HIDDEN; - m_join.players.items = NULL; - m_join.players.numItems = 0; - - m_join.menu.statusbar = "Press Space to refresh; Hold ALT to refresh all"; - } + serverSlot_t *s = &m_join.servers[m_join.list.curvalue]; + + if( s->valid ) { + m_join.info.generic.flags &= ~QMF_HIDDEN; + m_join.info.items = ( void ** )s->rules; + m_join.info.numItems = s->numRules; + + if( s->numPlayers ) { + m_join.players.generic.flags &= ~QMF_HIDDEN; + m_join.players.items = ( void ** )s->players; + m_join.players.numItems = s->numPlayers; + } else { + m_join.players.generic.flags |= QMF_HIDDEN; + m_join.players.items = NULL; + m_join.players.numItems = 0; + } + + m_join.menu.status = "Press Enter to connect; Space to refresh"; + } else { + m_join.info.generic.flags |= QMF_HIDDEN; + m_join.info.items = NULL; + m_join.info.numItems = 0; + + m_join.players.generic.flags |= QMF_HIDDEN; + m_join.players.items = NULL; + m_join.players.numItems = 0; + + m_join.menu.status = "Press Space to refresh; Hold ALT to refresh all"; + } } static void ClearSlot( serverSlot_t *slot ) { @@ -105,46 +104,46 @@ static void ClearSlot( serverSlot_t *slot ) { } void UI_AddToServerList( const serverStatus_t *status ) { - serverSlot_t *slot; - int i, j, k; - char *host, *map; - const char *info = status->infostring; - char key[MAX_STRING_CHARS]; - char value[MAX_STRING_CHARS]; - const playerStatus_t *player; + serverSlot_t *slot; + int i, j, k; + char *host, *map; + const char *info = status->infostring; + char key[MAX_STRING_CHARS]; + char value[MAX_STRING_CHARS]; + const playerStatus_t *player; if( !m_join.active ) { return; } - // see if already added - for( i = 0, slot = m_join.servers; i < m_join.list.numItems; i++, slot++ ) { - if( !strcmp( status->address, slot->realAddress ) ) { - break; - } - } - - if( i == m_join.list.numItems ) { - // create new slot - if( m_join.list.numItems == MAX_STATUS_SERVERS ) { - return; - } + // see if already added + for( i = 0, slot = m_join.servers; i < m_join.list.numItems; i++, slot++ ) { + if( !strcmp( status->address, slot->realAddress ) ) { + break; + } + } + + if( i == m_join.list.numItems ) { + // create new slot + if( m_join.list.numItems == MAX_STATUS_SERVERS ) { + return; + } strcpy( slot->realAddress, status->address ); strcpy( slot->address, status->address ); if( !m_join.cursorSet ) { m_join.list.curvalue = i; m_join.cursorSet = qtrue; } - m_join.list.numItems++; + m_join.list.numItems++; m_join.names[m_join.list.numItems] = NULL; - } + } host = Info_ValueForKey( info, "hostname" ); if( !host[0] ) { host = slot->address; } - map = Info_ValueForKey( info, "mapname" ); + map = Info_ValueForKey( info, "mapname" ); if( !map[0] ) { map = "???"; } else { @@ -161,284 +160,275 @@ void UI_AddToServerList( const serverStatus_t *status ) { status->numPlayers < j ? k > 0 ? S_COLOR_YELLOW : "" : S_COLOR_RED, status->numPlayers, j ); - if( m_join.names[i] ) { - com.Free( m_join.names[i] ); - } - m_join.names[i] = UI_FormatColumns( 0, host, map, key, NULL ); + if( m_join.names[i] ) { + com.Free( m_join.names[i] ); + } + m_join.names[i] = UI_FormatColumns( 0, host, map, key, NULL ); ClearSlot( slot ); - do { - Info_NextPair( &info, key, value ); - if( !key[0] ) { - break; - } - slot->rules[slot->numRules++] = + do { + Info_NextPair( &info, key, value ); + if( !key[0] ) { + break; + } + slot->rules[slot->numRules++] = UI_FormatColumns( 0, key, value, NULL ); - } while( info && slot->numRules < MAX_STATUS_RULES ); + } while( info && slot->numRules < MAX_STATUS_RULES ); - for( i = 0, player = status->players ; i < status->numPlayers; i++, player++ ) { + for( i = 0, player = status->players ; i < status->numPlayers; i++, player++ ) { Com_sprintf( key, sizeof( key ), "%d", player->score ); Com_sprintf( value, sizeof( value ), "%d", player->ping ); - slot->players[i] = UI_FormatColumns( 0, - key, value, player->name, NULL ); - } - slot->numPlayers = status->numPlayers; + slot->players[i] = UI_FormatColumns( 0, + key, value, player->name, NULL ); + } + slot->numPlayers = status->numPlayers; - slot->valid = qtrue; + slot->valid = qtrue; UpdateSelection(); } static void PingSelected( void ) { - serverSlot_t *s = &m_join.servers[m_join.list.curvalue]; + serverSlot_t *s = &m_join.servers[m_join.list.curvalue]; - if( m_join.names[m_join.list.curvalue] ) { - com.Free( m_join.names[m_join.list.curvalue] ); - } - m_join.names[m_join.list.curvalue] = UI_FormatColumns( 0, + if( m_join.names[m_join.list.curvalue] ) { + com.Free( m_join.names[m_join.list.curvalue] ); + } + m_join.names[m_join.list.curvalue] = UI_FormatColumns( 0, s->address, "???", "?/?", NULL ); ClearSlot( s ); UpdateSelection(); - m_join.menu.statusbar = "Pinging servers, please wait..."; + m_join.menu.status = "Pinging servers, please wait..."; client.UpdateScreen(); - client.SendStatusRequest( s->realAddress, 0 ); + client.SendStatusRequest( s->realAddress, 0 ); - UpdateSelection(); + UpdateSelection(); } static void AddUnlistedServers( void ) { - serverSlot_t *slot; + serverSlot_t *slot; cvar_t *var; - int i, j; + int i, j; m_join.active = qtrue; // ping broadcast client.SendStatusRequest( NULL, 0 ); - for( i = 0; i < MAX_STATUS_SERVERS; i++ ) { - var = cvar.Find( va( "adr%i", i ) ); + for( i = 0; i < MAX_STATUS_SERVERS; i++ ) { + var = cvar.Find( va( "adr%i", i ) ); if( !var ) { break; } - if( !var->string[0] ) { - continue; - } + if( !var->string[0] ) { + continue; + } - // ignore if already listed - for( j = 0, slot = m_join.servers; j < m_join.list.numItems; j++, slot++ ) { - if( !Q_stricmp( var->string, slot->address ) ) { - break; - } - } + // ignore if already listed + for( j = 0, slot = m_join.servers; j < m_join.list.numItems; j++, slot++ ) { + if( !Q_stricmp( var->string, slot->address ) ) { + break; + } + } - if( j != m_join.list.numItems ) { - continue; - } + if( j != m_join.list.numItems ) { + continue; + } - if( m_join.list.numItems == MAX_STATUS_SERVERS ) { - break; - } + if( m_join.list.numItems == MAX_STATUS_SERVERS ) { + break; + } // save original address Q_strncpyz( slot->address, var->string, sizeof( slot->address ) ); Q_strncpyz( slot->realAddress, var->string, sizeof( slot->realAddress ) ); - m_join.names[m_join.list.numItems++] = UI_FormatColumns( 0, + m_join.names[m_join.list.numItems++] = UI_FormatColumns( 0, slot->address, "???", "?/?", NULL ); // ping and resolve real ip client.SendStatusRequest( slot->realAddress, sizeof( slot->realAddress ) ); client.UpdateScreen(); - } + } } static void FreeListedServers( void ) { - int i; + int i; - for( i = 0; i < m_join.list.numItems; i++ ) { + for( i = 0; i < m_join.list.numItems; i++ ) { ClearSlot( &m_join.servers[i] ); - } - - for( i = 0; i < m_join.list.numItems; i++ ) { - if( m_join.names[i] ) { - com.Free( m_join.names[i] ); - m_join.names[i] = NULL; - } - } - - m_join.list.numItems = 0; - m_join.info.items = NULL; - m_join.info.numItems = 0; - //m_join.list.curvalue = 0; - //m_join.list.prestep = 0; + } + + for( i = 0; i < m_join.list.numItems; i++ ) { + if( m_join.names[i] ) { + com.Free( m_join.names[i] ); + m_join.names[i] = NULL; + } + } + + m_join.list.numItems = 0; + m_join.info.items = NULL; + m_join.info.numItems = 0; + //m_join.list.curvalue = 0; + //m_join.list.prestep = 0; m_join.active = qfalse; } static void PingServers( void ) { - FreeListedServers(); - client.StopAllSounds(); - UpdateSelection(); + FreeListedServers(); + client.StopAllSounds(); + UpdateSelection(); - m_join.menu.statusbar = "Pinging servers, please wait..."; + m_join.menu.status = "Pinging servers, please wait..."; client.UpdateScreen(); - // send out info packets - AddUnlistedServers(); + // send out info packets + AddUnlistedServers(); - UpdateSelection(); + UpdateSelection(); +} + +static menuSound_t Connect( menuCommon_t *self ) { + serverSlot_t *s = &m_join.servers[m_join.list.curvalue]; + + cmd.ExecuteText( EXEC_APPEND, va( "connect \"%s\"\n", s->realAddress ) ); + UI_PopMenu(); + return QMS_IN; +} + +static menuSound_t Change( menuCommon_t *self ) { + UpdateSelection(); + return QMS_MOVE; } -static void Resize( void ) { - int w1 = uis.width * 0.75f; - int w2 = uis.width * 0.25f; +static void Size( menuFrameWork_t *self ) { + int w1 = uis.width * 0.75f; + int w2 = uis.width * 0.25f; // // server list // - m_join.list.generic.x = 0; - m_join.list.generic.y = 8; - m_join.list.generic.height = uis.height / 2 - 8; + m_join.list.generic.x = 0; + m_join.list.generic.y = 8; + m_join.list.generic.height = uis.height / 2 - 8; - m_join.list.columns[0].width = w1 - 144; - m_join.list.columns[1].width = 80; - m_join.list.columns[2].width = 64; + m_join.list.columns[0].width = w1 - 144; + m_join.list.columns[1].width = 80; + m_join.list.columns[2].width = 64; // // server info // - m_join.info.generic.y = uis.height / 2 + 1; - m_join.info.generic.height = uis.height / 2 - 8 - 2; + m_join.info.generic.y = uis.height / 2 + 1; + m_join.info.generic.height = uis.height / 2 - 8 - 2; - m_join.info.columns[0].width = w1 / 2; - m_join.info.columns[1].width = w1 - w1 / 2; + m_join.info.columns[0].width = w1 / 2; + m_join.info.columns[1].width = w1 - w1 / 2; // // player list // - m_join.players.generic.x = w1 + 10; - m_join.players.generic.y = 8; - m_join.players.generic.height = uis.height - 16 - 1; + m_join.players.generic.x = w1 + 10; + m_join.players.generic.y = 8; + m_join.players.generic.height = uis.height - 16 - 1; - m_join.players.columns[0].width = 32; - m_join.players.columns[1].width = 32; - m_join.players.columns[2].width = w2 - 64; + m_join.players.columns[0].width = 32; + m_join.players.columns[1].width = 32; + m_join.players.columns[2].width = w2 - 64; } -static int JoinServer_MenuCallback( int id, int msg, int param ) { - serverSlot_t *s = &m_join.servers[m_join.list.curvalue]; - switch( msg ) { - case QM_ACTIVATE: - if( id == ID_LIST ) { - cmd.ExecuteText( EXEC_APPEND, - va( "connect \"%s\"\n", s->realAddress ) ); - UI_PopMenu(); - return QMS_IN; - } - break; - case QM_KEY: - if( param == 'r' ) { - cvar.Set( "rcon_address", s->realAddress ); - return QMS_SILENT; - } - if( param == ' ' ) { - if( !keys.IsDown( K_ALT ) ) { - PingSelected(); - } else { - PingServers(); - } - return QMS_SILENT; - } - break; - case QM_CHANGE: - if( id == ID_LIST ) { - UpdateSelection(); - return QMS_MOVE; +static menuSound_t Keydown( menuFrameWork_t *self, int key ) { + serverSlot_t *s = &m_join.servers[m_join.list.curvalue]; + + switch( key ) { + case 'r': + cvar.Set( "rcon_address", s->realAddress ); + return QMS_SILENT; + case ' ': + if( !Key_IsDown( K_ALT ) ) { + PingSelected(); + } else { + PingServers(); } - break; - case QM_DESTROY: - FreeListedServers(); - break; - case QM_DESTROY_CHILD: - FreeListedServers(); - AddUnlistedServers(); - break; - case QM_SIZE: - Resize(); - break; - default: - break; - } - - return QMS_NOTHANDLED; + return QMS_SILENT; + default: + return QMS_NOTHANDLED; + } +} + +static void Pop( menuFrameWork_t *self ) { + FreeListedServers(); +} + +static qboolean Push( menuFrameWork_t *self ) { + PingServers(); + return qtrue; } -void JoinServer_MenuInit( void ) { - memset( &m_join, 0, sizeof( m_join ) ); +void M_Menu_Servers( void ) { + m_join.menu.name = "servers"; + m_join.menu.title = "Server Browser"; + + m_join.menu.push = Push; + m_join.menu.pop = Pop; + m_join.menu.size = Size; + m_join.menu.keydown = Keydown; // // server list // - m_join.list.generic.type = MTYPE_LIST; - m_join.list.generic.id = ID_LIST; - m_join.list.generic.flags = QMF_LEFT_JUSTIFY|QMF_HASFOCUS; - m_join.list.items = ( void ** )m_join.names; - m_join.list.numcolumns = 3; - - m_join.list.columns[0].uiFlags = UI_LEFT; - m_join.list.columns[0].name = "Hostname"; - m_join.list.columns[1].uiFlags = UI_CENTER; - m_join.list.columns[1].name = "Map"; - m_join.list.columns[2].uiFlags = UI_CENTER; - m_join.list.columns[2].name = "Players"; + m_join.list.generic.type = MTYPE_LIST; + m_join.list.generic.flags = QMF_LEFT_JUSTIFY|QMF_HASFOCUS; + m_join.list.generic.activate = Connect; + m_join.list.generic.change = Change; + m_join.list.items = ( void ** )m_join.names; + m_join.list.numcolumns = 3; + + m_join.list.columns[0].uiFlags = UI_LEFT; + m_join.list.columns[0].name = "Hostname"; + m_join.list.columns[1].uiFlags = UI_CENTER; + m_join.list.columns[1].name = "Map"; + m_join.list.columns[2].uiFlags = UI_CENTER; + m_join.list.columns[2].name = "Players"; // // server info // - m_join.info.generic.type = MTYPE_LIST; - m_join.info.generic.flags = QMF_LEFT_JUSTIFY|QMF_HIDDEN; - m_join.info.numcolumns = 2; + m_join.info.generic.type = MTYPE_LIST; + m_join.info.generic.flags = QMF_LEFT_JUSTIFY|QMF_HIDDEN; + m_join.info.numcolumns = 2; - m_join.info.columns[0].uiFlags = UI_LEFT; - m_join.info.columns[0].name = "Key"; - m_join.info.columns[1].uiFlags = UI_LEFT; - m_join.info.columns[1].name = "Value"; + m_join.info.columns[0].uiFlags = UI_LEFT; + m_join.info.columns[0].name = "Key"; + m_join.info.columns[1].uiFlags = UI_LEFT; + m_join.info.columns[1].name = "Value"; // // player list // - m_join.players.generic.type = MTYPE_LIST; - m_join.players.generic.flags = QMF_LEFT_JUSTIFY|QMF_HIDDEN|QMF_DISABLED; - m_join.players.mlFlags = MLF_HIDE_SCROLLBAR; - m_join.players.numcolumns = 3; - - m_join.players.columns[0].uiFlags = UI_CENTER; - m_join.players.columns[0].name = "Frg"; - m_join.players.columns[1].uiFlags = UI_CENTER; - m_join.players.columns[1].name = "RTT"; - m_join.players.columns[2].uiFlags = UI_LEFT; - m_join.players.columns[2].name = "Name"; - - m_join.menu.callback = JoinServer_MenuCallback; - m_join.menu.banner = "Server Browser"; - - Menu_AddItem( &m_join.menu, &m_join.list ); - Menu_AddItem( &m_join.menu, &m_join.info ); - Menu_AddItem( &m_join.menu, &m_join.players ); -} - - -void M_Menu_Multiplayer_f( void ) { - JoinServer_MenuInit(); - UI_PushMenu( &m_join.menu ); - - PingServers(); + m_join.players.generic.type = MTYPE_LIST; + m_join.players.generic.flags = QMF_LEFT_JUSTIFY|QMF_HIDDEN|QMF_DISABLED; + m_join.players.mlFlags = MLF_HIDE_SCROLLBAR; + m_join.players.numcolumns = 3; + + m_join.players.columns[0].uiFlags = UI_CENTER; + m_join.players.columns[0].name = "Frg"; + m_join.players.columns[1].uiFlags = UI_CENTER; + m_join.players.columns[1].name = "RTT"; + m_join.players.columns[2].uiFlags = UI_LEFT; + m_join.players.columns[2].name = "Name"; + + Menu_AddItem( &m_join.menu, &m_join.list ); + Menu_AddItem( &m_join.menu, &m_join.info ); + Menu_AddItem( &m_join.menu, &m_join.players ); + + List_Append( &ui_menus, &m_join.menu.entry ); } |