/*
=================
UI_Main_ActivateFunc
=================
*/
static void UI_Main_ActivateFunc( void )
{
	if ( !CL_IsActive( ))
		uiMain.resumeGame.generic.flags |= QMF_HIDDEN;

	if( gpGlobals->developer )
	{
		uiMain.console.generic.y = CL_IsActive() ? 180 : 230;
		UI_ScaleCoords( NULL, &uiMain.console.generic.y, NULL, NULL );
	}
}
/*
=================
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;
	}
}
Exemple #3
0
/*
=================
UI_PopMenu
=================
*/
void UI_PopMenu( void )
{
	UI_StartSound( uiSoundOut );

	uiStatic.menuDepth--;

	if( uiStatic.menuDepth < 0 )
		HOST_ERROR( "UI_PopMenu: menu stack underflow\n" );

	UI_PopPButtonStack();

	if( uiStatic.menuDepth )
	{
		uiStatic.menuActive = uiStatic.menuStack[uiStatic.menuDepth-1];
		uiStatic.firstDraw = true;
	}
	else if ( CL_IsActive( ))
	{
		UI_CloseMenu();
	}
	else
	{
		// never trying the close menu when client isn't connected
		KEY_SetDest( KEY_MENU );
		UI_Main_Menu();
	}

	if( uiStatic.m_fDemosPlayed && uiStatic.m_iOldMenuDepth == uiStatic.menuDepth )
	{
		CLIENT_COMMAND( FALSE, "demos\n" );
		uiStatic.m_fDemosPlayed = false;
		uiStatic.m_iOldMenuDepth = 0;
	}
}
/*
=================
UI_PopMenu
=================
*/
void UI_PopMenu( void )
{
	UI_StartSound( uiSoundOut );

	uiStatic.menuDepth--;

	if( uiStatic.menuDepth < 0 )
		HOST_ERROR( "UI_PopMenu: menu stack underflow\n" );

	UI_PopPButtonStack();

	if( uiStatic.menuDepth )
	{
		uiStatic.menuActive = uiStatic.menuStack[uiStatic.menuDepth-1];
		uiStatic.firstDraw = true;
	}
	else if ( CL_IsActive( ))
	{
		UI_CloseMenu();
	}
	else
	{
		// never trying the close menu when client isn't connected
		KEY_SetDest( KEY_MENU );
		UI_Main_Menu();
	}
}
/*
=================
UI_Main_KeyFunc
=================
*/
static const char *UI_Main_KeyFunc( int key, int down )
{
	if( down && key == K_ESCAPE )
	{
		if ( CL_IsActive( ))
		{
			if(!( uiMain.dlgMessage1.generic.flags & QMF_HIDDEN ))
				UI_PromptDialog();
			else if(!( uiMain.quitMessage.generic.flags & QMF_HIDDEN ))
				UI_QuitDialog();
			else UI_CloseMenu();
		}
		else UI_QuitDialog();
		return uiSoundNull;
	}
	return UI_DefaultKey( &uiMain.menu, key, down );
}
/*
=================
UI_CustomGame_Callback
=================
*/
static void UI_CustomGame_Callback( void *self, int event )
{
	menuCommon_s	*item = (menuCommon_s *)self;

	if( event == QM_CHANGED )
	{
		// aee if the load button should be grayed
		if( !stricmp( gMenu.m_gameinfo.gamefolder, uiCustomGame.modsDir[uiCustomGame.modList.curItem] ))
			uiCustomGame.load.generic.flags |= QMF_GRAYED;
		else uiCustomGame.load.generic.flags &= ~QMF_GRAYED;

		if( strlen( uiCustomGame.modsWebSites[uiCustomGame.modList.curItem] ) == 0 )
			uiCustomGame.go2url.generic.flags |= QMF_GRAYED;
		else uiCustomGame.go2url.generic.flags &= ~QMF_GRAYED;
		return;
	}

	if( event != QM_ACTIVATED )
		return;

	switch( item->id )
	{
	case ID_DONE:
		UI_PopMenu();
		break;
	case ID_GOTOSITE:
		if( strlen( uiCustomGame.modsWebSites[uiCustomGame.modList.curItem] ))
			SHELL_EXECUTE( uiCustomGame.modsWebSites[uiCustomGame.modList.curItem], NULL, false );
		break;
	case ID_ACTIVATE:
	case ID_NO:
		if ( CL_IsActive( ))
		{
			UI_EndGameDialog();
			break;	// don't f**k up the game
		}
	case ID_YES:
		// restart all engine systems with new game
		char cmd[128];
		sprintf( cmd, "game %s\n", uiCustomGame.modsDir[uiCustomGame.modList.curItem] );
		CLIENT_COMMAND( FALSE, cmd );
		UI_EndGameDialog();
		break;
	}
}
static void UI_PromptDialog( float skill )
{
	if ( CL_IsActive( ) == FALSE )
	{
		UI_NewGame_StartGame( skill );
		return;
	}
	
	uiNewGame.skill = skill;

	// toggle main menu between active\inactive
	// show\hide quit dialog
	uiNewGame.easy.generic.flags ^= QMF_INACTIVE; 
	uiNewGame.medium.generic.flags ^= QMF_INACTIVE;
	uiNewGame.hard.generic.flags ^= QMF_INACTIVE;
	uiNewGame.cancel.generic.flags ^= QMF_INACTIVE;

	uiNewGame.msgBox.generic.flags ^= QMF_HIDDEN;
	uiNewGame.dlgMessage1.generic.flags ^= QMF_HIDDEN;
	uiNewGame.no.generic.flags ^= QMF_HIDDEN;
	uiNewGame.yes.generic.flags ^= QMF_HIDDEN;

}
Exemple #8
0
/*
=================
UI_UpdateMenu
=================
*/
void UI_UpdateMenu( float flTime )
{
	if( !uiStatic.initialized )
		return;

	UI_DrawFinalCredits ();

	if( !uiStatic.visible )
		return;

	if( !uiStatic.menuActive )
		return;

	uiStatic.realTime = flTime * 1000;
	uiStatic.framecount++;

	if( CVAR_GET_FLOAT( "cl_background" ) && !g_engfuncs.pfnClientInGame())
		return;	// don't draw menu while level is loading

	if( uiStatic.firstDraw )
	{
		// we loading background so skip SCR_Update
		if( UI_StartBackGroundMap( )) return;

		if( uiStatic.menuActive->activateFunc )
			uiStatic.menuActive->activateFunc();
	}

	// draw menu
	if( uiStatic.menuActive->drawFunc )
		uiStatic.menuActive->drawFunc();
	else UI_DrawMenu( uiStatic.menuActive );

	if( uiStatic.firstDraw )
	{
		uiStatic.firstDraw = false;
		static int first = TRUE;
                    
		if( first )
		{
			// if game was launched with commandline e.g. +map or +load ignore the music
			if( !CL_IsActive( ))
				BACKGROUND_TRACK( "gamestartup", "gamestartup" );
			first = FALSE;
		}
	}

	//CR
	UI_DrawTitleAnim();
	//

	// draw cursor
	UI_DrawMouseCursor();

	// delay playing the enter sound until after the menu has been
	// drawn, to avoid delay while caching images
	if( uiStatic.enterSound > 0.0f && uiStatic.enterSound <= gpGlobals->time )
	{
		UI_StartSound( uiSoundIn );
		uiStatic.enterSound = -1;
	}
}
/*
=================
UI_SaveGame_Callback
=================
*/
static void UI_SaveGame_Callback( void *self, int event )
{
	menuCommon_s	*item = (menuCommon_s *)self;

	if( event == QM_CHANGED )
	{
		// never overwrite existing saves, because their names was never get collision
		if ( strlen( uiSaveGame.saveName[uiSaveGame.savesList.curItem] ) == 0 || CL_IsActive() == FALSE )
			uiSaveGame.save.generic.flags |= QMF_GRAYED;
		else uiSaveGame.save.generic.flags &= ~QMF_GRAYED;

		if ( strlen( uiSaveGame.delName[uiSaveGame.savesList.curItem] ) == 0 )
			uiSaveGame.remove.generic.flags |= QMF_GRAYED;
		else uiSaveGame.remove.generic.flags &= ~QMF_GRAYED;
		return;
	}

	if( event != QM_ACTIVATED )
		return;
	
	switch( item->id )
	{
	case ID_CANCEL:
		UI_PopMenu();
		break;
	case ID_SAVE:
		if( strlen( uiSaveGame.saveName[uiSaveGame.savesList.curItem] ))
		{
			char	cmd[128];

			sprintf( cmd, "save/%s.bmp", uiSaveGame.saveName[uiSaveGame.savesList.curItem] );
			PIC_Free( cmd );

			sprintf( cmd, "save \"%s\"\n", uiSaveGame.saveName[uiSaveGame.savesList.curItem] );
			CLIENT_COMMAND( FALSE, cmd );
			UI_CloseMenu();
		}
		break;
	case ID_NO:
	case ID_DELETE:
		UI_DeleteDialog();
		break;
	case ID_YES:
		if( strlen( uiSaveGame.delName[uiSaveGame.savesList.curItem] ))
		{
			char	cmd[128];
			sprintf( cmd, "killsave \"%s\"\n", uiSaveGame.delName[uiSaveGame.savesList.curItem] );

			CLIENT_COMMAND( TRUE, cmd );

			sprintf( cmd, "save/%s.bmp", uiSaveGame.delName[uiSaveGame.savesList.curItem] );
			PIC_Free( cmd );

			// restarts the menu
			UI_PopMenu();
			UI_SaveGame_Menu();
			return;
		}
		UI_DeleteDialog();
		break;
	}
}
/*
=================
UI_SaveGame_GetGameList
=================
*/
static void UI_SaveGame_GetGameList( void )
{
	char	comment[256];
	char	**filenames;
	int	i = 0, j, numFiles;

	filenames = FS_SEARCH( "save/*.sav", &numFiles, TRUE );

	// sort the saves in reverse order (oldest past at the end)
	qsort( filenames, numFiles, sizeof( char* ), (cmpfunc)COM_CompareSaves );

	if ( CL_IsActive() && !gpGlobals->demoplayback )
	{
		// create new entry for current save game
		strncpy( uiSaveGame.saveName[i], "new", CS_SIZE );
		StringConcat( uiSaveGame.saveDescription[i], "Current", TIME_LENGTH );
		StringConcat( uiSaveGame.saveDescription[i], uiEmptyString, TIME_LENGTH ); // fill remaining entries
		StringConcat( uiSaveGame.saveDescription[i], "New Saved Game", NAME_LENGTH );
		StringConcat( uiSaveGame.saveDescription[i], uiEmptyString, NAME_LENGTH );
		StringConcat( uiSaveGame.saveDescription[i], "New", GAMETIME_LENGTH );
		StringConcat( uiSaveGame.saveDescription[i], uiEmptyString, GAMETIME_LENGTH );
		uiSaveGame.saveDescriptionPtr[i] = uiSaveGame.saveDescription[i];
		i++;
	}

	for ( j = 0; j < numFiles; i++, j++ )
	{
		if ( i >= UI_MAXGAMES )
			break;
		
		if ( !GET_SAVE_COMMENT( filenames[j], comment ))
		{
			if ( strlen( comment ))
			{
				// get name string even if not found - SV_GetComment can be mark saves
				// as <CORRUPTED> <OLD VERSION> etc
				StringConcat( uiSaveGame.saveDescription[i], uiEmptyString, TIME_LENGTH );
				StringConcat( uiSaveGame.saveDescription[i], comment, NAME_LENGTH );
				StringConcat( uiSaveGame.saveDescription[i], uiEmptyString, NAME_LENGTH );
				uiSaveGame.saveDescriptionPtr[i] = uiSaveGame.saveDescription[i];
				COM_FileBase( filenames[j], uiSaveGame.saveName[i] );
				COM_FileBase( filenames[j], uiSaveGame.delName[i] );
			}
			else uiSaveGame.saveDescriptionPtr[i] = NULL;
			continue;
		}

		// strip path, leave only filename (empty slots doesn't have savename)
		COM_FileBase( filenames[j], uiSaveGame.saveName[i] );
		COM_FileBase( filenames[j], uiSaveGame.delName[i] );

		// fill save desc
		StringConcat( uiSaveGame.saveDescription[i], comment + CS_SIZE, TIME_LENGTH );
		StringConcat( uiSaveGame.saveDescription[i], " ", TIME_LENGTH );
		StringConcat( uiSaveGame.saveDescription[i], comment + CS_SIZE + CS_TIME, TIME_LENGTH );
		StringConcat( uiSaveGame.saveDescription[i], uiEmptyString, TIME_LENGTH ); // fill remaining entries
		StringConcat( uiSaveGame.saveDescription[i], comment, NAME_LENGTH );
		StringConcat( uiSaveGame.saveDescription[i], uiEmptyString, NAME_LENGTH );
		StringConcat( uiSaveGame.saveDescription[i], comment + CS_SIZE + (CS_TIME * 2), GAMETIME_LENGTH );
		StringConcat( uiSaveGame.saveDescription[i], uiEmptyString, GAMETIME_LENGTH );
		uiSaveGame.saveDescriptionPtr[i] = uiSaveGame.saveDescription[i];
	}

	for ( ; i < UI_MAXGAMES; i++ )
		uiSaveGame.saveDescriptionPtr[i] = NULL;

	uiSaveGame.savesList.itemNames = (const char **)uiSaveGame.saveDescriptionPtr;

	if ( strlen( uiSaveGame.saveName[0] ) == 0 || CL_IsActive() == FALSE )
		uiSaveGame.save.generic.flags |= QMF_GRAYED;
	else uiSaveGame.save.generic.flags &= ~QMF_GRAYED;

	if ( strlen( uiSaveGame.delName[0] ) == 0 )
		uiSaveGame.remove.generic.flags |= QMF_GRAYED;
	else uiSaveGame.remove.generic.flags &= ~QMF_GRAYED;
}
/*
=================
UI_Main_Init
=================
*/
static void UI_Main_Init( void )
{
	bool bCustomGame;

	memset( &uiMain, 0, sizeof( uiMain_t ));

	if( CVAR_GET_FLOAT( "host_allow_changegame" ))
		bCustomGame = true;
	else bCustomGame = false;

	// precache .avi file and get logo width and height
	PRECACHE_LOGO( "logo.avi" );

	uiMain.menu.vidInitFunc = UI_Main_Init;
	uiMain.menu.keyFunc = UI_Main_KeyFunc;
	uiMain.menu.activateFunc = UI_Main_ActivateFunc;

	uiMain.background.generic.id = ID_BACKGROUND;
	uiMain.background.generic.type = QMTYPE_BITMAP;
	uiMain.background.generic.flags = QMF_INACTIVE;
	uiMain.background.generic.x = 0;
	uiMain.background.generic.y = 0;
	uiMain.background.generic.width = uiStatic.width;
	uiMain.background.generic.height = 768;
	uiMain.background.pic = ART_BACKGROUND;
	uiMain.background.generic.ownerdraw = UI_Background_Ownerdraw;

	uiMain.console.generic.id = ID_CONSOLE;
	uiMain.console.generic.type = QMTYPE_BM_BUTTON;
	uiMain.console.generic.name = "Console";
	uiMain.console.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
	uiMain.console.generic.x = 72;
	uiMain.console.generic.y = CL_IsActive() ? 180 : 230;
	uiMain.console.generic.callback = UI_Main_Callback;

	UI_UtilSetupPicButton( &uiMain.console, PC_CONSOLE );

	uiMain.resumeGame.generic.id = ID_RESUME;
	uiMain.resumeGame.generic.type = QMTYPE_BM_BUTTON;
	uiMain.resumeGame.generic.name = "Resume game";
	uiMain.resumeGame.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_NOTIFY;
	uiMain.resumeGame.generic.statusText = MenuStrings[HINT_RESUME_GAME];
	uiMain.resumeGame.generic.x = 72;
	uiMain.resumeGame.generic.y = 230;
	uiMain.resumeGame.generic.callback = UI_Main_Callback;

	UI_UtilSetupPicButton( &uiMain.resumeGame, PC_RESUME_GAME );

	uiMain.newGame.generic.id = ID_NEWGAME;
	uiMain.newGame.generic.type = QMTYPE_BM_BUTTON;
	uiMain.newGame.generic.name = "New game";
	uiMain.newGame.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_NOTIFY;
	uiMain.newGame.generic.statusText = MenuStrings[HINT_NEWGAME];
	uiMain.newGame.generic.x = 72;
	uiMain.newGame.generic.y = 280;
	uiMain.newGame.generic.callback = UI_Main_Callback;

	UI_UtilSetupPicButton( &uiMain.newGame, PC_NEW_GAME );

	if ( gMenu.m_gameinfo.gamemode == GAME_MULTIPLAYER_ONLY || !strlen( gMenu.m_gameinfo.startmap ))
		uiMain.newGame.generic.flags |= QMF_GRAYED;

	uiMain.saveRestore.generic.id = ID_SAVERESTORE;
	uiMain.saveRestore.generic.type = QMTYPE_BM_BUTTON;
	uiMain.saveRestore.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_NOTIFY;

	// server.dll needs for reading savefiles or startup newgame
	if( !CheckGameDll( ))
	{
		uiMain.saveRestore.generic.flags |= QMF_GRAYED;
		uiMain.newGame.generic.flags |= QMF_GRAYED;
	}

	if( CL_IsActive( ))
	{
		uiMain.saveRestore.generic.name = "Save\\Load Game";
		uiMain.saveRestore.generic.statusText = MenuStrings[HINT_SAVELOADGAME];
		UI_UtilSetupPicButton(&uiMain.saveRestore,PC_SAVE_LOAD_GAME);
	}
	else
	{
		uiMain.saveRestore.generic.name = "Load Game";
		uiMain.saveRestore.generic.statusText = MenuStrings[HINT_LOADGAME];
		uiMain.resumeGame.generic.flags |= QMF_HIDDEN;
		UI_UtilSetupPicButton( &uiMain.saveRestore, PC_LOAD_GAME );
	}

	uiMain.saveRestore.generic.x = 72;
	uiMain.saveRestore.generic.y = 330;
	uiMain.saveRestore.generic.callback = UI_Main_Callback;

	uiMain.configuration.generic.id = ID_CONFIGURATION;
	uiMain.configuration.generic.type = QMTYPE_BM_BUTTON;
	uiMain.configuration.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_NOTIFY;
	uiMain.configuration.generic.name = "Configuration";
	uiMain.configuration.generic.statusText = MenuStrings[HINT_CONFIGURATION];
	uiMain.configuration.generic.x = 72;
	uiMain.configuration.generic.y = 380;
	uiMain.configuration.generic.callback = UI_Main_Callback;

	UI_UtilSetupPicButton( &uiMain.configuration, PC_CONFIG );

	uiMain.multiPlayer.generic.id = ID_MULTIPLAYER;
	uiMain.multiPlayer.generic.type = QMTYPE_BM_BUTTON;
	uiMain.multiPlayer.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_NOTIFY;
	uiMain.multiPlayer.generic.name = "Multiplayer";
	uiMain.multiPlayer.generic.statusText = MenuStrings[HINT_MULTIPLAYER];
	uiMain.multiPlayer.generic.x = 72;
	uiMain.multiPlayer.generic.y = 430;
	uiMain.multiPlayer.generic.callback = UI_Main_Callback;

	UI_UtilSetupPicButton( &uiMain.multiPlayer, PC_MULTIPLAYER );

	if ( gMenu.m_gameinfo.gamemode == GAME_SINGLEPLAYER_ONLY )
		uiMain.multiPlayer.generic.flags |= QMF_GRAYED;

	if ( gMenu.m_gameinfo.gamemode == GAME_MULTIPLAYER_ONLY )
	{
		uiMain.saveRestore.generic.flags |= QMF_GRAYED;
	}

	uiMain.customGame.generic.id = ID_CUSTOMGAME;
	uiMain.customGame.generic.type = QMTYPE_BM_BUTTON;
	uiMain.customGame.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_NOTIFY;
	uiMain.customGame.generic.name = "Custom Game";
	uiMain.customGame.generic.statusText = MenuStrings[HINT_CUSTOM_GAME];
	uiMain.customGame.generic.x = 72;
	uiMain.customGame.generic.y = 480;
	uiMain.customGame.generic.callback = UI_Main_Callback;

	UI_UtilSetupPicButton( &uiMain.customGame, PC_CUSTOM_GAME );

	uiMain.previews.generic.id = ID_PREVIEWS;
	uiMain.previews.generic.type = QMTYPE_BM_BUTTON;
	uiMain.previews.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_NOTIFY;
	uiMain.previews.generic.name = "Previews";
	uiMain.previews.generic.statusText = MenuStrings[HINT_PREVIEWS_TEXT];
	uiMain.previews.generic.x = 72;
	uiMain.previews.generic.y = (bCustomGame) ? 530 : 480;
	uiMain.previews.generic.callback = UI_Main_Callback;

	// too short execute string - not a real command
	if( strlen( MenuStrings[HINT_PREVIEWS_CMD] ) <= 3 )
		uiMain.previews.generic.flags |= QMF_GRAYED;

	UI_UtilSetupPicButton( &uiMain.previews, PC_PREVIEWS );

	uiMain.quit.generic.id = ID_QUIT;
	uiMain.quit.generic.type = QMTYPE_BM_BUTTON;
	uiMain.quit.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_NOTIFY;
	uiMain.quit.generic.name = "Quit";
	uiMain.quit.generic.statusText = MenuStrings[HINT_QUIT_BUTTON];
	uiMain.quit.generic.x = 72;
	uiMain.quit.generic.y = (bCustomGame) ? 580 : 530;
	uiMain.quit.generic.callback = UI_Main_Callback;

	UI_UtilSetupPicButton( &uiMain.quit, PC_QUIT );

	uiMain.minimizeBtn.generic.id = ID_MINIMIZE;
	uiMain.minimizeBtn.generic.type = QMTYPE_BITMAP;
	uiMain.minimizeBtn.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_MOUSEONLY|QMF_ACT_ONRELEASE;
	uiMain.minimizeBtn.generic.x = uiStatic.width - 72;
	uiMain.minimizeBtn.generic.y = 13;
	uiMain.minimizeBtn.generic.width = 32;
	uiMain.minimizeBtn.generic.height = 32;
	uiMain.minimizeBtn.generic.callback = UI_Main_Callback;
	uiMain.minimizeBtn.pic = ART_MINIMIZE_N;
	uiMain.minimizeBtn.focusPic = ART_MINIMIZE_F;

	uiMain.quitButton.generic.id = ID_QUIT_BUTTON;
	uiMain.quitButton.generic.type = QMTYPE_BITMAP;
	uiMain.quitButton.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_MOUSEONLY|QMF_ACT_ONRELEASE;
	uiMain.quitButton.generic.x = uiStatic.width - 36;
	uiMain.quitButton.generic.y = 13;
	uiMain.quitButton.generic.width = 32;
	uiMain.quitButton.generic.height = 32;
	uiMain.quitButton.generic.callback = UI_Main_Callback;
	uiMain.quitButton.pic = ART_CLOSEBTN_N;
	uiMain.quitButton.focusPic = ART_CLOSEBTN_F;

	uiMain.msgBox.generic.id = ID_MSGBOX;
	uiMain.msgBox.generic.type = QMTYPE_ACTION;
	uiMain.msgBox.generic.flags = QMF_INACTIVE|QMF_HIDDEN;
	uiMain.msgBox.generic.ownerdraw = UI_MsgBox_Ownerdraw; // just a fill rectangle
	uiMain.msgBox.generic.x = DLG_X + 192;
	uiMain.msgBox.generic.y = 256;
	uiMain.msgBox.generic.width = 640;
	uiMain.msgBox.generic.height = 256;

	uiMain.quitMessage.generic.id = ID_MSGBOX;
	uiMain.quitMessage.generic.type = QMTYPE_ACTION;
	uiMain.quitMessage.generic.flags = QMF_INACTIVE|QMF_DROPSHADOW|QMF_HIDDEN|QMF_CENTER_JUSTIFY;
	uiMain.quitMessage.generic.name = (CL_IsActive( )) ? MenuStrings[HINT_QUIT_ACTIVE] : MenuStrings[HINT_QUIT];
	uiMain.quitMessage.generic.x = DLG_X + 192;
	uiMain.quitMessage.generic.y = 280;
	uiMain.quitMessage.generic.width = 640;
	uiMain.quitMessage.generic.height = 256;

	uiMain.dlgMessage1.generic.id = ID_MSGTEXT;
	uiMain.dlgMessage1.generic.type = QMTYPE_ACTION;
	uiMain.dlgMessage1.generic.flags = QMF_INACTIVE|QMF_DROPSHADOW|QMF_HIDDEN|QMF_CENTER_JUSTIFY;
	uiMain.dlgMessage1.generic.name = MenuStrings[HINT_RESTART_GAME];
	uiMain.dlgMessage1.generic.x = DLG_X + 192;
	uiMain.dlgMessage1.generic.y = 280;
	uiMain.dlgMessage1.generic.width = 640;
	uiMain.dlgMessage1.generic.height = 256;

	uiMain.yes.generic.id = ID_YES;
	uiMain.yes.generic.type = QMTYPE_BM_BUTTON;
	uiMain.yes.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_HIDDEN;
	uiMain.yes.generic.name = "Ok";
	uiMain.yes.generic.x = DLG_X + 380;
	uiMain.yes.generic.y = 460;
	uiMain.yes.generic.callback = UI_Main_Callback;

	UI_UtilSetupPicButton( &uiMain.yes, PC_OK );

	uiMain.no.generic.id = ID_NO;
	uiMain.no.generic.type = QMTYPE_BM_BUTTON;
	uiMain.no.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|QMF_HIDDEN;
	uiMain.no.generic.name = "Cancel";
	uiMain.no.generic.x = DLG_X + 530;
	uiMain.no.generic.y = 460;
	uiMain.no.generic.callback = UI_Main_Callback;
	
	UI_UtilSetupPicButton( &uiMain.no, PC_CANCEL );

	UI_AddItem( &uiMain.menu, (void *)&uiMain.background );

	if ( gpGlobals->developer )
		UI_AddItem( &uiMain.menu, (void *)&uiMain.console );

	UI_AddItem( &uiMain.menu, (void *)&uiMain.resumeGame );
	UI_AddItem( &uiMain.menu, (void *)&uiMain.newGame );

	UI_AddItem( &uiMain.menu, (void *)&uiMain.saveRestore );
	UI_AddItem( &uiMain.menu, (void *)&uiMain.configuration );
	UI_AddItem( &uiMain.menu, (void *)&uiMain.multiPlayer );

	if ( bCustomGame )
		UI_AddItem( &uiMain.menu, (void *)&uiMain.customGame );

	UI_AddItem( &uiMain.menu, (void *)&uiMain.previews );
	UI_AddItem( &uiMain.menu, (void *)&uiMain.quit );
	UI_AddItem( &uiMain.menu, (void *)&uiMain.minimizeBtn );
	UI_AddItem( &uiMain.menu, (void *)&uiMain.quitButton );
	UI_AddItem( &uiMain.menu, (void *)&uiMain.msgBox );
	UI_AddItem( &uiMain.menu, (void *)&uiMain.quitMessage );
	UI_AddItem( &uiMain.menu, (void *)&uiMain.dlgMessage1 );
	UI_AddItem( &uiMain.menu, (void *)&uiMain.no );
	UI_AddItem( &uiMain.menu, (void *)&uiMain.yes );
}
/*
=================
UI_Main_Callback
=================
*/
static void UI_Main_Callback( void *self, int event )
{
	menuCommon_s	*item = (menuCommon_s *)self;

	switch( item->id )
	{
	case ID_QUIT_BUTTON:
		if( event == QM_PRESSED )
			((menuBitmap_s *)self)->focusPic = ART_CLOSEBTN_D;
		else ((menuBitmap_s *)self)->focusPic = ART_CLOSEBTN_F;
		break;
	case ID_MINIMIZE:
		if( event == QM_PRESSED )
			((menuBitmap_s *)self)->focusPic = ART_MINIMIZE_D;
		else ((menuBitmap_s *)self)->focusPic = ART_MINIMIZE_F;
		break;
	}

	if( event != QM_ACTIVATED )
		return;

	switch( item->id )
	{
	case ID_CONSOLE:
		UI_SetActiveMenu( FALSE );
		KEY_SetDest( KEY_CONSOLE );
		break;
	case ID_RESUME:
		UI_CloseMenu();
		break;
	case ID_NEWGAME:
		if( CL_IsActive( ))
			UI_PromptDialog();
		else UI_Main_NewGame();
		break;
	case ID_MULTIPLAYER:
		UI_MultiPlayer_Menu();
		break;
	case ID_CONFIGURATION:
		UI_Options_Menu();
		break;
	case ID_SAVERESTORE:
		if( CL_IsActive( ))
			UI_SaveLoad_Menu();
		else UI_LoadGame_Menu();
		break;
	case ID_CUSTOMGAME:
		UI_CustomGame_Menu();
		break;
	case ID_PREVIEWS:
		SHELL_EXECUTE( MenuStrings[HINT_PREVIEWS_CMD], NULL, false );
		break;
	case ID_QUIT:
	case ID_QUIT_BUTTON:
		UI_QuitDialog();
		break;
	case ID_MINIMIZE:
		CLIENT_COMMAND( FALSE, "minimize\n" );
		break;
	case ID_YES:
		if( !( uiMain.quitMessage.generic.flags & QMF_HIDDEN ))
			CLIENT_COMMAND( FALSE, "quit\n" );
		else UI_Main_NewGame();
		break;
	case ID_NO:
		if( !( uiMain.quitMessage.generic.flags & QMF_HIDDEN ))
			UI_QuitDialog();
		else UI_PromptDialog();
		break;
	}
}
/*
=================
UI_RecDemo_Callback
=================
*/
static void UI_RecDemo_Callback( void *self, int event )
{
	menuCommon_s	*item = (menuCommon_s *)self;

	if( event == QM_CHANGED )
	{
		// never overwrite existing saves, because their names was never get collision
		if( strlen( uiRecDemo.demoName[uiRecDemo.demosList.curItem] ) == 0 || !CL_IsActive() || gpGlobals->demoplayback )
			uiRecDemo.record.generic.flags |= QMF_GRAYED;
		else uiRecDemo.record.generic.flags &= ~QMF_GRAYED;

		if( strlen( uiRecDemo.delName[uiRecDemo.demosList.curItem] ) == 0 || !stricmp( gpGlobals->demoname, uiRecDemo.delName[uiRecDemo.demosList.curItem] ))
			uiRecDemo.remove.generic.flags |= QMF_GRAYED;
		else uiRecDemo.remove.generic.flags &= ~QMF_GRAYED;
		return;
	}

	if( event != QM_ACTIVATED )
		return;
	
	switch( item->id )
	{
	case ID_CANCEL:
		UI_PopMenu();
		break;
	case ID_RECORD:
		if( gpGlobals->demorecording )
		{
			CLIENT_COMMAND( FALSE, "stop" );
			uiRecDemo.record.generic.name = "Record";
			uiRecDemo.record.generic.statusText = "Record a new demo";
			uiRecDemo.remove.generic.flags &= ~QMF_GRAYED;
		}
		else if( strlen( uiRecDemo.demoName[uiRecDemo.demosList.curItem] ))
		{
			char	cmd[128];

			sprintf( cmd, "demos/%s.bmp", uiRecDemo.demoName[uiRecDemo.demosList.curItem] );
			PIC_Free( cmd );

			sprintf( cmd, "record \"%s\"\n", uiRecDemo.demoName[uiRecDemo.demosList.curItem] );
			CLIENT_COMMAND( FALSE, cmd );
			UI_CloseMenu();
		}
		break;
	case ID_NO:
	case ID_DELETE:
		UI_DeleteDialog();
		break;
	case ID_YES:
		if( strlen( uiRecDemo.delName[uiRecDemo.demosList.curItem] ))
		{
			char	cmd[128];
			sprintf( cmd, "killdemo \"%s\"\n", uiRecDemo.delName[uiRecDemo.demosList.curItem] );

			CLIENT_COMMAND( TRUE, cmd );

			sprintf( cmd, "demos/%s.bmp", uiRecDemo.delName[uiRecDemo.demosList.curItem] );
			PIC_Free( cmd );

			// restarts the menu
			UI_PopMenu();
			UI_RecDemo_Menu();
			return;
		}
		UI_DeleteDialog();
		break;
	}
}
/*
=================
UI_RecDemo_GetDemoList
=================
*/
static void UI_RecDemo_GetDemoList( void )
{
	char	comment[256];
	char	**filenames;
	int	i = 0, j, numFiles;

	filenames = FS_SEARCH( "demos/*.dem", &numFiles, TRUE );

	if ( CL_IsActive () && !gpGlobals->demorecording && !gpGlobals->demoplayback )
	{
		char maxClients[32];
		sprintf( maxClients, "%i", gpGlobals->maxClients );

		// create new entry for current save game
		strncpy( uiRecDemo.demoName[i], "new", CS_SIZE );
		StringConcat( uiRecDemo.demoDescription[i], gpGlobals->maptitle, TITLE_LENGTH );
		StringConcat( uiRecDemo.demoDescription[i], uiEmptyString, TITLE_LENGTH ); // fill remaining entries
		StringConcat( uiRecDemo.demoDescription[i], "New Demo", MAPNAME_LENGTH );
		StringConcat( uiRecDemo.demoDescription[i], uiEmptyString, MAPNAME_LENGTH );
		StringConcat( uiRecDemo.demoDescription[i], maxClients, MAXCLIENTS_LENGTH );
		StringConcat( uiRecDemo.demoDescription[i], uiEmptyString, MAXCLIENTS_LENGTH );
		uiRecDemo.demoDescriptionPtr[i] = uiRecDemo.demoDescription[i];
		i++;
	}

	for( j = 0; j < numFiles; i++, j++ )
	{
		if( i >= UI_MAXGAMES ) break;
		
		if( !GET_DEMO_COMMENT( filenames[j], comment ))
		{
			if( strlen( comment ))
			{
				// get name string even if not found - C:_GetComment can be mark demos
				// as <CORRUPTED> <OLD VERSION> etc
				// get name string even if not found - SV_GetComment can be mark saves
				// as <CORRUPTED> <OLD VERSION> etc
				StringConcat( uiRecDemo.demoDescription[i], uiEmptyString, TITLE_LENGTH );
				StringConcat( uiRecDemo.demoDescription[i], comment, MAPNAME_LENGTH );
				StringConcat( uiRecDemo.demoDescription[i], uiEmptyString, MAXCLIENTS_LENGTH );
				uiRecDemo.demoDescriptionPtr[i] = uiRecDemo.demoDescription[i];
				COM_FileBase( filenames[j], uiRecDemo.demoName[i] );
				COM_FileBase( filenames[j], uiRecDemo.delName[i] );
			}
			else uiRecDemo.demoDescriptionPtr[i] = NULL;
			continue;
		}

		// strip path, leave only filename (empty slots doesn't have demoname)
		COM_FileBase( filenames[j], uiRecDemo.demoName[i] );
		COM_FileBase( filenames[j], uiRecDemo.delName[i] );

		// fill demo desc
		StringConcat( uiRecDemo.demoDescription[i], comment + CS_SIZE, TITLE_LENGTH );
		StringConcat( uiRecDemo.demoDescription[i], uiEmptyString, TITLE_LENGTH );
		StringConcat( uiRecDemo.demoDescription[i], comment, MAPNAME_LENGTH );
		StringConcat( uiRecDemo.demoDescription[i], uiEmptyString, MAPNAME_LENGTH ); // fill remaining entries
		StringConcat( uiRecDemo.demoDescription[i], comment + CS_SIZE * 2, MAXCLIENTS_LENGTH );
		StringConcat( uiRecDemo.demoDescription[i], uiEmptyString, MAXCLIENTS_LENGTH );
		uiRecDemo.demoDescriptionPtr[i] = uiRecDemo.demoDescription[i];
	}

	for ( ; i < UI_MAXGAMES; i++ )
		uiRecDemo.demoDescriptionPtr[i] = NULL;
	uiRecDemo.demosList.itemNames = (const char **)uiRecDemo.demoDescriptionPtr;

	if( strlen( uiRecDemo.demoName[0] ) == 0 || !CL_IsActive () || gpGlobals->demoplayback )
		uiRecDemo.record.generic.flags |= QMF_GRAYED;
	else uiRecDemo.record.generic.flags &= ~QMF_GRAYED;

	if( strlen( uiRecDemo.delName[0] ) == 0 || !stricmp( gpGlobals->demoname, uiRecDemo.delName[uiRecDemo.demosList.curItem] ))
		uiRecDemo.remove.generic.flags |= QMF_GRAYED;
	else uiRecDemo.remove.generic.flags &= ~QMF_GRAYED;
}