cs16-client-legacy/mainui/menu_internetgames.cpp

470 lines
16 KiB
C++

/*
Copyright (C) 1997-2001 Id Software, Inc.
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "extdll.h"
#include "basemenu.h"
#include "utils.h"
#include "keydefs.h"
#include "menu_btnsbmp_table.h"
#define ART_BANNER "gfx/shell/head_inetgames"
#define ID_BACKGROUND 0
#define ID_BANNER 1
#define ID_JOINGAME 2
#define ID_CREATEGAME 3
#define ID_GAMEINFO 4
#define ID_REFRESH 5
#define ID_DONE 6
#define ID_SERVERSLIST 7
#define ID_TABLEHINT 8
#define ID_MSGBOX 9
#define ID_MSGTEXT 10
#define ID_YES 130
#define ID_NO 131
#define GAME_LENGTH 18
#define MAPNAME_LENGTH 20+GAME_LENGTH
#define TYPE_LENGTH 16+MAPNAME_LENGTH
#define MAXCL_LENGTH 15+TYPE_LENGTH
typedef struct
{
char gameDescription[UI_MAX_SERVERS][256];
char *gameDescriptionPtr[UI_MAX_SERVERS];
menuFramework_s menu;
menuBitmap_s background;
menuBitmap_s banner;
menuPicButton_s joinGame;
menuPicButton_s createGame;
menuPicButton_s gameInfo;
menuPicButton_s refresh;
menuPicButton_s done;
// joingame prompt dialog
menuAction_s msgBox;
menuAction_s dlgMessage1;
menuAction_s dlgMessage2;
menuPicButton_s yes;
menuPicButton_s no;
menuScrollList_s gameList;
menuAction_s hintMessage;
char hintText[MAX_HINT_TEXT];
int refreshTime;
} uiInternetGames_t;
static uiInternetGames_t uiInternetGames;
static void UI_PromptDialog( void )
{
// toggle main menu between active\inactive
// show\hide quit dialog
uiInternetGames.joinGame.generic.flags ^= QMF_INACTIVE;
uiInternetGames.createGame.generic.flags ^= QMF_INACTIVE;
uiInternetGames.gameInfo.generic.flags ^= QMF_INACTIVE;
uiInternetGames.refresh.generic.flags ^= QMF_INACTIVE;
uiInternetGames.done.generic.flags ^= QMF_INACTIVE;
uiInternetGames.gameList.generic.flags ^= QMF_INACTIVE;
uiInternetGames.msgBox.generic.flags ^= QMF_HIDDEN;
uiInternetGames.dlgMessage1.generic.flags ^= QMF_HIDDEN;
uiInternetGames.dlgMessage2.generic.flags ^= QMF_HIDDEN;
uiInternetGames.no.generic.flags ^= QMF_HIDDEN;
uiInternetGames.yes.generic.flags ^= QMF_HIDDEN;
}
/*
=================
UI_InternetGames_KeyFunc
=================
*/
static const char *UI_InternetGames_KeyFunc( int key, int down )
{
if( down && key == K_ESCAPE && !( uiInternetGames.dlgMessage1.generic.flags & QMF_HIDDEN ))
{
UI_PromptDialog();
return uiSoundNull;
}
return UI_DefaultKey( &uiInternetGames.menu, key, down );
}
/*
=================
UI_InternetGames_GetGamesList
=================
*/
static void UI_InternetGames_GetGamesList( void )
{
int i;
const char *info;
for( i = 0; i < uiStatic.numServers; i++ )
{
if( i >= UI_MAX_SERVERS ) break;
info = uiStatic.serverNames[i];
StringConcat( uiInternetGames.gameDescription[i], Info_ValueForKey( info, "host" ), GAME_LENGTH );
AddSpaces( uiInternetGames.gameDescription[i], GAME_LENGTH );
StringConcat( uiInternetGames.gameDescription[i], Info_ValueForKey( info, "map" ), MAPNAME_LENGTH );
AddSpaces( uiInternetGames.gameDescription[i], MAPNAME_LENGTH );
if( !strcmp( Info_ValueForKey( info, "dm" ), "1" ))
StringConcat( uiInternetGames.gameDescription[i], "deathmatch", TYPE_LENGTH );
else if( !strcmp( Info_ValueForKey( info, "coop" ), "1" ))
StringConcat( uiInternetGames.gameDescription[i], "coop", TYPE_LENGTH );
else if( !strcmp( Info_ValueForKey( info, "team" ), "1" ))
StringConcat( uiInternetGames.gameDescription[i], "teamplay", TYPE_LENGTH );
AddSpaces( uiInternetGames.gameDescription[i], TYPE_LENGTH );
StringConcat( uiInternetGames.gameDescription[i], Info_ValueForKey( info, "numcl" ), MAXCL_LENGTH );
StringConcat( uiInternetGames.gameDescription[i], "\\", MAXCL_LENGTH );
StringConcat( uiInternetGames.gameDescription[i], Info_ValueForKey( info, "maxcl" ), MAXCL_LENGTH );
AddSpaces( uiInternetGames.gameDescription[i], MAXCL_LENGTH );
uiInternetGames.gameDescriptionPtr[i] = uiInternetGames.gameDescription[i];
}
for( ; i < UI_MAX_SERVERS; i++ )
uiInternetGames.gameDescriptionPtr[i] = NULL;
uiInternetGames.gameList.itemNames = (const char **)uiInternetGames.gameDescriptionPtr;
uiInternetGames.gameList.numItems = 0; // reset it
if( !uiInternetGames.gameList.generic.charHeight )
return; // to avoid divide integer by zero
// count number of items
while( uiInternetGames.gameList.itemNames[uiInternetGames.gameList.numItems] )
uiInternetGames.gameList.numItems++;
// calculate number of visible rows
uiInternetGames.gameList.numRows = (uiInternetGames.gameList.generic.height2 / uiInternetGames.gameList.generic.charHeight) - 2;
if( uiInternetGames.gameList.numRows > uiInternetGames.gameList.numItems ) uiInternetGames.gameList.numRows = uiInternetGames.gameList.numItems;
if( uiStatic.numServers )
uiInternetGames.joinGame.generic.flags &= ~QMF_GRAYED;
}
/*
=================
UI_InternetGames_JoinGame
=================
*/
static void UI_InternetGames_JoinGame( void )
{
if( !strlen( uiInternetGames.gameDescription[uiInternetGames.gameList.curItem] ))
return;
CLIENT_JOIN( uiStatic.serverAddresses[uiInternetGames.gameList.curItem] );
}
/*
=================
UI_Background_Ownerdraw
=================
*/
static void UI_Background_Ownerdraw( void *self )
{
menuCommon_s *item = (menuCommon_s *)self;
if( !CVAR_GET_FLOAT( "cl_background" ))
UI_DrawBackground_Callback( self );
if( uiStatic.realTime > uiInternetGames.refreshTime )
{
uiInternetGames.refreshTime = uiStatic.realTime + 10000; // refresh every 10 secs
UI_RefreshInternetServerList();
}
// serverinfo has been changed update display
if( uiStatic.updateServers )
{
UI_InternetGames_GetGamesList ();
uiStatic.updateServers = false;
}
}
/*
=================
UI_MsgBox_Ownerdraw
=================
*/
static void UI_MsgBox_Ownerdraw( void *self )
{
menuCommon_s *item = (menuCommon_s *)self;
UI_FillRect( item->x, item->y, item->width, item->height, uiPromptBgColor );
}
/*
=================
UI_InternetGames_Callback
=================
*/
static void UI_InternetGames_Callback( void *self, int event )
{
menuCommon_s *item = (menuCommon_s *)self;
if( event != QM_ACTIVATED )
return;
switch( item->id )
{
case ID_JOINGAME:
if( CL_IsActive( ))
UI_PromptDialog();
else UI_InternetGames_JoinGame();
break;
case ID_CREATEGAME:
CVAR_SET_FLOAT( "public", 1.0f );
UI_CreateGame_Menu();
break;
case ID_GAMEINFO:
// UNDONE: not implemented
break;
case ID_REFRESH:
UI_RefreshInternetServerList();
break;
case ID_DONE:
UI_PopMenu();
break;
case ID_YES:
UI_InternetGames_JoinGame();
break;
case ID_NO:
UI_PromptDialog();
break;
}
}
/*
=================
UI_InternetGames_Init
=================
*/
static void UI_InternetGames_Init( void )
{
memset( &uiInternetGames, 0, sizeof( uiInternetGames_t ));
uiInternetGames.menu.vidInitFunc = UI_InternetGames_Init;
uiInternetGames.menu.keyFunc = UI_InternetGames_KeyFunc;
StringConcat( uiInternetGames.hintText, "Game", GAME_LENGTH );
AddSpaces( uiInternetGames.hintText, GAME_LENGTH );
StringConcat( uiInternetGames.hintText, "Map", MAPNAME_LENGTH );
AddSpaces( uiInternetGames.hintText, MAPNAME_LENGTH );
StringConcat( uiInternetGames.hintText, "Type", TYPE_LENGTH );
AddSpaces( uiInternetGames.hintText, TYPE_LENGTH );
StringConcat( uiInternetGames.hintText, "Num/Max Clients", MAXCL_LENGTH );
AddSpaces( uiInternetGames.hintText, MAXCL_LENGTH );
uiInternetGames.background.generic.id = ID_BACKGROUND;
uiInternetGames.background.generic.type = QMTYPE_BITMAP;
uiInternetGames.background.generic.flags = QMF_INACTIVE;
uiInternetGames.background.generic.x = 0;
uiInternetGames.background.generic.y = 0;
uiInternetGames.background.generic.width = uiStatic.width;
uiInternetGames.background.generic.height = 768;
uiInternetGames.background.pic = ART_BACKGROUND;
uiInternetGames.background.generic.ownerdraw = UI_Background_Ownerdraw;
uiInternetGames.banner.generic.id = ID_BANNER;
uiInternetGames.banner.generic.type = QMTYPE_BITMAP;
uiInternetGames.banner.generic.flags = QMF_INACTIVE|QMF_DRAW_ADDITIVE;
uiInternetGames.banner.generic.x = UI_BANNER_POSX;
uiInternetGames.banner.generic.y = UI_BANNER_POSY;
uiInternetGames.banner.generic.width = UI_BANNER_WIDTH;
uiInternetGames.banner.generic.height = UI_BANNER_HEIGHT;
uiInternetGames.banner.pic = ART_BANNER;
uiInternetGames.joinGame.generic.id = ID_JOINGAME;
uiInternetGames.joinGame.generic.type = QMTYPE_BM_BUTTON;
uiInternetGames.joinGame.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_GRAYED;
uiInternetGames.joinGame.generic.x = 72;
uiInternetGames.joinGame.generic.y = 230;
uiInternetGames.joinGame.generic.name = "Join game";
uiInternetGames.joinGame.generic.statusText = "Join to selected game";
uiInternetGames.joinGame.generic.callback = UI_InternetGames_Callback;
UI_UtilSetupPicButton( &uiInternetGames.joinGame, PC_JOIN_GAME );
uiInternetGames.createGame.generic.id = ID_CREATEGAME;
uiInternetGames.createGame.generic.type = QMTYPE_BM_BUTTON;
uiInternetGames.createGame.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
uiInternetGames.createGame.generic.x = 72;
uiInternetGames.createGame.generic.y = 280;
uiInternetGames.createGame.generic.name = "Create game";
uiInternetGames.createGame.generic.statusText = "Create new Internet game";
uiInternetGames.createGame.generic.callback = UI_InternetGames_Callback;
UI_UtilSetupPicButton( &uiInternetGames.createGame, PC_CREATE_GAME );
uiInternetGames.gameInfo.generic.id = ID_GAMEINFO;
uiInternetGames.gameInfo.generic.type = QMTYPE_BM_BUTTON;
uiInternetGames.gameInfo.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_GRAYED;
uiInternetGames.gameInfo.generic.x = 72;
uiInternetGames.gameInfo.generic.y = 330;
uiInternetGames.gameInfo.generic.name = "View game info";
uiInternetGames.gameInfo.generic.statusText = "Get detail game info";
uiInternetGames.gameInfo.generic.callback = UI_InternetGames_Callback;
UI_UtilSetupPicButton( &uiInternetGames.gameInfo, PC_VIEW_GAME_INFO );
uiInternetGames.refresh.generic.id = ID_REFRESH;
uiInternetGames.refresh.generic.type = QMTYPE_BM_BUTTON;
uiInternetGames.refresh.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
uiInternetGames.refresh.generic.x = 72;
uiInternetGames.refresh.generic.y = 380;
uiInternetGames.refresh.generic.name = "Refresh";
uiInternetGames.refresh.generic.statusText = "Refresh servers list";
uiInternetGames.refresh.generic.callback = UI_InternetGames_Callback;
UI_UtilSetupPicButton( &uiInternetGames.refresh, PC_REFRESH );
uiInternetGames.done.generic.id = ID_DONE;
uiInternetGames.done.generic.type = QMTYPE_BM_BUTTON;
uiInternetGames.done.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
uiInternetGames.done.generic.x = 72;
uiInternetGames.done.generic.y = 430;
uiInternetGames.done.generic.name = "Done";
uiInternetGames.done.generic.statusText = "Return to main menu";
uiInternetGames.done.generic.callback = UI_InternetGames_Callback;
UI_UtilSetupPicButton( &uiInternetGames.done, PC_DONE );
uiInternetGames.msgBox.generic.id = ID_MSGBOX;
uiInternetGames.msgBox.generic.type = QMTYPE_ACTION;
uiInternetGames.msgBox.generic.flags = QMF_INACTIVE|QMF_HIDDEN;
uiInternetGames.msgBox.generic.ownerdraw = UI_MsgBox_Ownerdraw; // just a fill rectangle
uiInternetGames.msgBox.generic.x = DLG_X + 192;
uiInternetGames.msgBox.generic.y = 256;
uiInternetGames.msgBox.generic.width = 640;
uiInternetGames.msgBox.generic.height = 256;
uiInternetGames.dlgMessage1.generic.id = ID_MSGTEXT;
uiInternetGames.dlgMessage1.generic.type = QMTYPE_ACTION;
uiInternetGames.dlgMessage1.generic.flags = QMF_INACTIVE|QMF_HIDDEN|QMF_DROPSHADOW;
uiInternetGames.dlgMessage1.generic.name = "Join a network game will exit";
uiInternetGames.dlgMessage1.generic.x = DLG_X + 248;
uiInternetGames.dlgMessage1.generic.y = 280;
uiInternetGames.dlgMessage2.generic.id = ID_MSGTEXT;
uiInternetGames.dlgMessage2.generic.type = QMTYPE_ACTION;
uiInternetGames.dlgMessage2.generic.flags = QMF_INACTIVE|QMF_HIDDEN|QMF_DROPSHADOW;
uiInternetGames.dlgMessage2.generic.name = "any current game, OK to exit?";
uiInternetGames.dlgMessage2.generic.x = DLG_X + 248;
uiInternetGames.dlgMessage2.generic.y = 310;
uiInternetGames.yes.generic.id = ID_YES;
uiInternetGames.yes.generic.type = QMTYPE_BM_BUTTON;
uiInternetGames.yes.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_HIDDEN|QMF_DROPSHADOW;
uiInternetGames.yes.generic.name = "Ok";
uiInternetGames.yes.generic.x = DLG_X + 380;
uiInternetGames.yes.generic.y = 460;
uiInternetGames.yes.generic.callback = UI_InternetGames_Callback;
UI_UtilSetupPicButton( &uiInternetGames.yes, PC_OK );
uiInternetGames.no.generic.id = ID_NO;
uiInternetGames.no.generic.type = QMTYPE_BM_BUTTON;
uiInternetGames.no.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_HIDDEN|QMF_DROPSHADOW;
uiInternetGames.no.generic.name = "Cancel";
uiInternetGames.no.generic.x = DLG_X + 530;
uiInternetGames.no.generic.y = 460;
uiInternetGames.no.generic.callback = UI_InternetGames_Callback;
UI_UtilSetupPicButton( &uiInternetGames.no, PC_CANCEL );
uiInternetGames.hintMessage.generic.id = ID_TABLEHINT;
uiInternetGames.hintMessage.generic.type = QMTYPE_ACTION;
uiInternetGames.hintMessage.generic.flags = QMF_INACTIVE|QMF_SMALLFONT;
uiInternetGames.hintMessage.generic.color = uiColorHelp;
uiInternetGames.hintMessage.generic.name = uiInternetGames.hintText;
uiInternetGames.hintMessage.generic.x = 360;
uiInternetGames.hintMessage.generic.y = 225;
uiInternetGames.gameList.generic.id = ID_SERVERSLIST;
uiInternetGames.gameList.generic.type = QMTYPE_SCROLLLIST;
uiInternetGames.gameList.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_SMALLFONT;
uiInternetGames.gameList.generic.x = 360;
uiInternetGames.gameList.generic.y = 255;
uiInternetGames.gameList.generic.width = 640;
uiInternetGames.gameList.generic.height = 440;
uiInternetGames.gameList.generic.callback = UI_InternetGames_Callback;
uiInternetGames.gameList.itemNames = (const char **)uiInternetGames.gameDescriptionPtr;
// server.dll needs for reading savefiles or startup newgame
if( !CheckGameDll( ))
uiInternetGames.createGame.generic.flags |= QMF_GRAYED; // server.dll is missed - remote servers only
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.background );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.banner );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.joinGame );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.createGame );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.gameInfo );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.refresh );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.done );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.hintMessage );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.gameList );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.msgBox );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.dlgMessage1 );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.dlgMessage2 );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.no );
UI_AddItem( &uiInternetGames.menu, (void *)&uiInternetGames.yes );
uiInternetGames.refreshTime = uiStatic.realTime + 500; // delay before update 0.5 sec
}
/*
=================
UI_InternetGames_Precache
=================
*/
void UI_InternetGames_Precache( void )
{
PIC_Load( ART_BACKGROUND );
PIC_Load( ART_BANNER );
}
/*
=================
UI_InternetGames_Menu
=================
*/
void UI_InternetGames_Menu( void )
{
if ( gMenu.m_gameinfo.gamemode == GAME_SINGLEPLAYER_ONLY )
return;
// stop demos to allow network sockets to open
if ( gpGlobals->demoplayback && CVAR_GET_FLOAT( "cl_background" ))
{
uiStatic.m_iOldMenuDepth = uiStatic.menuDepth;
CLIENT_COMMAND( FALSE, "stop\n" );
uiStatic.m_fDemosPlayed = true;
}
UI_InternetGames_Precache();
UI_InternetGames_Init();
UI_PushMenu( &uiInternetGames.menu );
}