You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
838 lines
22 KiB
838 lines
22 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include <windows.h> |
|
#include "SDKLauncherDialog.h" |
|
#include "configs.h" |
|
|
|
#include <vgui_controls/ComboBox.h> |
|
#include <vgui_controls/ListPanel.h> |
|
#include <vgui_controls/ProgressBox.h> |
|
#include <vgui_controls/MessageBox.h> |
|
#include <vgui_controls/HTML.h> |
|
#include <vgui_controls/CheckButton.h> |
|
#include <vgui_controls/Divider.h> |
|
#include <vgui_controls/menu.h> |
|
#include <vgui/ISurface.h> |
|
#include <vgui/ILocalize.h> |
|
#include "vgui_controls/button.h" |
|
#include <vgui/ISystem.h> |
|
#include <vgui/IVGui.h> |
|
#include <vgui/iinput.h> |
|
#include <KeyValues.h> |
|
#include <FileSystem.h> |
|
#include <io.h> |
|
#include "CreateModWizard.h" |
|
#include "filesystem_tools.h" |
|
#include "min_footprint_files.h" |
|
#include "ConfigManager.h" |
|
#include "filesystem_tools.h" |
|
#include <iregistry.h> |
|
|
|
#include <sys/stat.h> |
|
#include "sdklauncher_main.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include <tier0/memdbgon.h> |
|
|
|
using namespace vgui; |
|
|
|
CSDKLauncherDialog *g_pSDKLauncherDialog = NULL; |
|
CGameConfigManager g_ConfigManager; |
|
char g_engineDir[50]; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Retrieves a URL out of the external localization file and opens it in a |
|
// web browser. |
|
// Input : *lpszLocalName - Localized name of the URL to open via shell execution |
|
//----------------------------------------------------------------------------- |
|
void OpenLocalizedURL( const char *lpszLocalName ) |
|
{ |
|
// Find and convert the localized unicode string |
|
char pURLStr[MAX_PATH]; |
|
wchar_t *pURLUni = g_pVGuiLocalize->Find( lpszLocalName ); |
|
g_pVGuiLocalize->ConvertUnicodeToANSI( pURLUni, pURLStr, sizeof( pURLStr ) ); |
|
|
|
// Open the URL through the shell |
|
vgui::system()->ShellExecute( "open", pURLStr ); |
|
} |
|
|
|
class CResetConfirmationMessageBox : public vgui::Frame |
|
{ |
|
public: |
|
typedef vgui::Frame BaseClass; |
|
|
|
CResetConfirmationMessageBox( Panel *pParent, const char *pPanelName ) |
|
: BaseClass( pParent, pPanelName ) |
|
{ |
|
SetSize( 200, 200 ); |
|
SetMinimumSize( 250, 100 ); |
|
SetSizeable( false ); |
|
LoadControlSettings( "resetconfirmbox.res" ); |
|
} |
|
void OnCommand( const char *command ) |
|
{ |
|
if ( Q_stricmp( command, "ResetConfigs" ) == 0 ) |
|
{ |
|
Close(); |
|
|
|
if ( GetVParent() ) |
|
{ |
|
PostMessage( GetVParent(), new KeyValues( "Command", "command", "ResetConfigs")); |
|
} |
|
} |
|
else if ( Q_stricmp( command, "MoreInfo" ) == 0 ) |
|
{ |
|
OpenLocalizedURL( "URL_Reset_Config" ); |
|
} |
|
|
|
BaseClass::OnCommand( command ); |
|
} |
|
}; |
|
|
|
class CConversionInfoMessageBox : public vgui::Frame |
|
{ |
|
public: |
|
typedef vgui::Frame BaseClass; |
|
|
|
CConversionInfoMessageBox( Panel *pParent, const char *pPanelName ) |
|
: BaseClass( pParent, pPanelName ) |
|
{ |
|
SetSize( 200, 200 ); |
|
SetMinimumSize( 250, 100 ); |
|
SetSizeable( false ); |
|
LoadControlSettings( "convinfobox.res" ); |
|
} |
|
|
|
virtual void OnCommand( const char *command ) |
|
{ |
|
BaseClass::OnCommand( command ); |
|
|
|
// For some weird reason, this dialog can |
|
if ( Q_stricmp( command, "ShowFAQ" ) == 0 ) |
|
{ |
|
OpenLocalizedURL( "URL_Convert_INI" ); |
|
} |
|
} |
|
}; |
|
|
|
class CGameInfoMessageBox : public vgui::Frame |
|
{ |
|
public: |
|
typedef vgui::Frame BaseClass; |
|
|
|
CGameInfoMessageBox( Panel *pParent, const char *pPanelName ) |
|
: BaseClass( pParent, pPanelName ) |
|
{ |
|
SetSize( 200, 200 ); |
|
SetMinimumSize( 250, 100 ); |
|
|
|
LoadControlSettings( "hl2infobox.res" ); |
|
} |
|
|
|
virtual void OnCommand( const char *command ) |
|
{ |
|
BaseClass::OnCommand( command ); |
|
|
|
// For some weird reason, this dialog can |
|
if ( Q_stricmp( command, "RunAnyway" ) == 0 ) |
|
{ |
|
m_pDialog->Launch( m_iActiveItem, true ); |
|
MarkForDeletion(); |
|
} |
|
else if ( Q_stricmp( command, "Troubleshooting" ) == 0 ) |
|
{ |
|
OpenLocalizedURL( "URL_SDK_FAQ" ); |
|
MarkForDeletion(); |
|
} |
|
} |
|
|
|
CSDKLauncherDialog *m_pDialog; |
|
int m_iActiveItem; |
|
}; |
|
|
|
class CMinFootprintRefreshConfirmationDialog : public vgui::Frame |
|
{ |
|
public: |
|
typedef vgui::Frame BaseClass; |
|
|
|
CMinFootprintRefreshConfirmationDialog( Panel *pParent, const char *pPanelName ) |
|
: BaseClass( pParent, pPanelName ) |
|
{ |
|
SetSizeable( false ); |
|
LoadControlSettings( "min_footprint_confirm_box.res" ); |
|
|
|
m_hOldModalSurface = input()->GetAppModalSurface(); |
|
input()->SetAppModalSurface( GetVPanel() ); |
|
} |
|
~CMinFootprintRefreshConfirmationDialog() |
|
{ |
|
input()->SetAppModalSurface( m_hOldModalSurface ); |
|
} |
|
|
|
void OnCommand( const char *command ) |
|
{ |
|
BaseClass::OnCommand( command ); |
|
|
|
if ( Q_stricmp( command, "Continue" ) == 0 ) |
|
{ |
|
PostMessage( g_pSDKLauncherDialog, new KeyValues( "Command", "command", "RefreshMinFootprint" ) ); |
|
MarkForDeletion(); |
|
} |
|
else if ( Q_stricmp( command, "Close" ) == 0 ) |
|
{ |
|
MarkForDeletion(); |
|
} |
|
} |
|
|
|
VPANEL m_hOldModalSurface; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
//----------------------------------------------------------------------------- |
|
CSDKLauncherDialog::CSDKLauncherDialog(vgui::Panel *parent, const char *name) : BaseClass(parent, name) |
|
{ |
|
Assert( !g_pSDKLauncherDialog ); |
|
g_pSDKLauncherDialog = this; |
|
|
|
SetSize(384, 480); |
|
SetMinimumSize(250, 200); |
|
|
|
SetMinimizeButtonVisible( true ); |
|
m_pImageList = new ImageList( true ); |
|
|
|
m_pMediaList = new SectionedListPanel(this, "MediaList"); |
|
m_pMediaList->AddActionSignalTarget( this ); |
|
m_pMediaList->SetImageList( m_pImageList, true ); |
|
|
|
m_pContextMenu = new Menu( m_pMediaList, "AppsContextMenu" ); |
|
|
|
m_pCurrentGameCombo = new ComboBox( this, "CurrentGameList", 8, false ); |
|
m_pCurrentGameCombo->AddActionSignalTarget( this ); |
|
|
|
m_pCurrentEngineCombo = new ComboBox( this, "CurrentEngineList", 4, false ); |
|
m_pCurrentEngineCombo->AddActionSignalTarget( this ); |
|
|
|
PopulateMediaList(); |
|
|
|
LoadControlSettings( "SDKLauncherDialog.res" ); |
|
|
|
GetEngineVersion( g_engineDir, sizeof( g_engineDir ) ); |
|
|
|
PopulateCurrentEngineCombo( false ); |
|
|
|
RefreshConfigs(); |
|
} |
|
|
|
CSDKLauncherDialog::~CSDKLauncherDialog() |
|
{ |
|
delete m_pMediaList; |
|
g_pSDKLauncherDialog = NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: kills the whole app on close |
|
//----------------------------------------------------------------------------- |
|
void CSDKLauncherDialog::OnClose() |
|
{ |
|
BaseClass::OnClose(); |
|
ivgui()->Stop(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: loads media list from file |
|
//----------------------------------------------------------------------------- |
|
void CSDKLauncherDialog::PopulateMediaList() |
|
{ |
|
KeyValues *dataFile = new KeyValues("Media"); |
|
dataFile->UsesEscapeSequences( true ); |
|
|
|
if (dataFile->LoadFromFile( g_pFullFileSystem, "MediaList.txt", NULL ) ) |
|
{ |
|
// Load all the images. |
|
KeyValues *pImages = dataFile->FindKey( "Images" ); |
|
if ( !pImages ) |
|
Error( "MediaList.txt missing Images key." ); |
|
|
|
for ( KeyValues *pCur=pImages->GetFirstTrueSubKey(); pCur; pCur=pCur->GetNextTrueSubKey() ) |
|
{ |
|
IImage *pImage = scheme()->GetImage( pCur->GetString( "Image", "" ), false ); |
|
int iIndex = pCur->GetInt( "Index", -1 ); |
|
if ( pImage && iIndex != -1 ) |
|
{ |
|
m_pImageList->SetImageAtIndex( iIndex, pImage ); |
|
} |
|
} |
|
|
|
// Load all the sections. |
|
KeyValues *pSections = dataFile->FindKey( "Sections" ); |
|
if ( !pSections ) |
|
Error( "MediaList.txt missing Sections key." ); |
|
|
|
for ( KeyValues *pSection=pSections->GetFirstTrueSubKey(); pSection; pSection=pSection->GetNextTrueSubKey() ) |
|
{ |
|
int id = pSection->GetInt( "id" ); |
|
const char *pName = pSection->GetString( "Name" ); |
|
m_pMediaList->AddSection( id, pName ); |
|
m_pMediaList->AddColumnToSection( id, "Image", "", SectionedListPanel::COLUMN_IMAGE, 20 ); |
|
m_pMediaList->AddColumnToSection( id, "Text", pName, 0, 200 ); |
|
|
|
// Set all the rows. |
|
for ( KeyValues *kv = pSection->GetFirstTrueSubKey(); kv != NULL; kv=kv->GetNextTrueSubKey() ) |
|
{ |
|
m_pMediaList->AddItem( id, kv ); |
|
} |
|
} |
|
} |
|
|
|
dataFile->deleteThis(); |
|
} |
|
|
|
void CSDKLauncherDialog::Launch( int hActiveListItem, bool bForce ) |
|
{ |
|
if (!m_pMediaList->IsItemIDValid(hActiveListItem)) |
|
return; |
|
|
|
// display the file |
|
KeyValues *item = m_pMediaList->GetItemData( hActiveListItem ); |
|
if ( !item ) |
|
return; |
|
|
|
// Is this a ShellExecute or a program they want to run? |
|
const char *pStr = item->GetString( "InlineProgram", NULL ); |
|
if ( pStr ) |
|
{ |
|
if ( Q_stricmp( pStr, "CreateMod" ) == 0 ) |
|
{ |
|
if ( !V_stricmp( g_engineDir, "ep1" ) || !V_stricmp( g_engineDir, "source2007" ) ) |
|
{ |
|
RunCreateModWizard( false ); |
|
} |
|
else |
|
{ |
|
VGUIMessageBox( this, "Unable to Run 'Create A Mod' Wizard", "Support for creating total conversions are not available using this engine versions." ); |
|
} |
|
} |
|
else if ( Q_stricmp( pStr, "refresh_min_footprint" ) == 0 ) |
|
{ |
|
CMinFootprintRefreshConfirmationDialog *pDlg = new CMinFootprintRefreshConfirmationDialog( this, "RefreshConfirmation" ); |
|
|
|
pDlg->RequestFocus(); |
|
pDlg->SetVisible( true ); |
|
pDlg->MoveToCenterOfScreen(); |
|
} |
|
else if ( Q_stricmp( pStr, "reset_configs" ) == 0 ) |
|
{ |
|
CResetConfirmationMessageBox *pDlg = new CResetConfirmationMessageBox( this, "ResetConfirmation" ); |
|
|
|
pDlg->RequestFocus(); |
|
pDlg->SetVisible( true ); |
|
pDlg->MoveToCenterOfScreen(); |
|
input()->SetAppModalSurface( pDlg->GetVPanel() ); |
|
} |
|
else |
|
{ |
|
Error( "Unknown InlineProgram value: %s", pStr ); |
|
} |
|
return; |
|
} |
|
|
|
pStr = item->GetString( "ShellExecute", NULL ); |
|
if ( pStr ) |
|
{ |
|
// Replace tokens we know about like %basedir%. |
|
system()->ShellExecute( "open", pStr ); |
|
return; |
|
} |
|
|
|
pStr = item->GetString( "Program", NULL ); |
|
if ( pStr ) |
|
{ |
|
// Get our current config. |
|
KeyValues *kv = m_pCurrentGameCombo->GetActiveItemUserData(); |
|
if ( !kv ) |
|
{ |
|
VGUIMessageBox( this, "Error", "No game configurations to run with." ); |
|
return; |
|
} |
|
|
|
const char *pModDir = kv->GetString( "ModDir", NULL ); |
|
if ( !pModDir ) |
|
{ |
|
VGUIMessageBox( this, "Error", "Missing 'ModDir' key/value." ); |
|
return; |
|
} |
|
|
|
bool bRun = true; |
|
if ( !bForce && Q_stristr( pStr, "%gamedir%" ) ) |
|
{ |
|
// Make sure the currently-selected gamedir is valid and has a gameinfo.txt in it. |
|
char testStr[MAX_PATH]; |
|
Q_strncpy( testStr, pModDir, sizeof( testStr ) ); |
|
Q_AppendSlash( testStr, sizeof( testStr ) ); |
|
Q_strncat( testStr, "gameinfo.txt", sizeof( testStr ), COPY_ALL_CHARACTERS ); |
|
if ( _access( testStr, 0 ) != 0 ) |
|
{ |
|
CGameInfoMessageBox *dlg = new CGameInfoMessageBox( this, "GameInfoMessageBox" ); |
|
|
|
dlg->m_pDialog = this; |
|
dlg->m_iActiveItem = hActiveListItem; |
|
|
|
dlg->RequestFocus(); |
|
dlg->SetVisible( true ); |
|
dlg->MoveToCenterOfScreen(); |
|
input()->SetAppModalSurface( dlg->GetVPanel() ); |
|
|
|
bRun = false; |
|
} |
|
} |
|
|
|
if ( bRun ) |
|
{ |
|
// Get the program name and its arguments. |
|
char programNameTemp[1024], programName[1024], launchDirectory[1024]; |
|
|
|
SubstituteBaseDir( pStr, programNameTemp, sizeof( programNameTemp ) ); |
|
V_StrSubst( programNameTemp, "%gamedir%", pModDir, programName, sizeof( programName ) ); |
|
V_strncpy( programNameTemp, programName, sizeof( programNameTemp ) ); |
|
V_StrSubst( programNameTemp, "%enginedir%", g_engineDir , programName, sizeof( programName ) ); |
|
|
|
V_strncpy( launchDirectory, GetSDKLauncherBaseDirectory(), sizeof( launchDirectory ) ); |
|
V_strncat( launchDirectory, "\\bin\\", sizeof( launchDirectory ) ); |
|
V_strncat( launchDirectory, g_engineDir, sizeof( launchDirectory ) ); |
|
|
|
// Check to see if we're running in tools mode |
|
if ( NULL != V_strstr( programName, "-tools" ) ) |
|
{ |
|
// We can't run tools mode in engine versions earlier than OB |
|
if ( !V_strcmp( g_engineDir, "ep1" ) ) |
|
{ |
|
VGUIMessageBox( this, "Error", "Source Engine Tools is not compatible with the selected engine version." ); |
|
return; |
|
} |
|
|
|
// If we are running the engine tools then change our launch directory to the game directory |
|
V_strncpy( launchDirectory, pModDir, sizeof( launchDirectory ) ); |
|
V_StripLastDir( launchDirectory, sizeof( launchDirectory ) ); |
|
V_strncat( launchDirectory, "bin", sizeof( launchDirectory ) ); |
|
} |
|
|
|
STARTUPINFO si; |
|
memset( &si, 0, sizeof( si ) ); |
|
si.cb = sizeof( si ); |
|
|
|
PROCESS_INFORMATION pi; |
|
memset( &pi, 0, sizeof( pi ) ); |
|
|
|
|
|
DWORD dwFlags = 0; |
|
if ( !CreateProcess( |
|
0, |
|
programName, |
|
NULL, // security |
|
NULL, |
|
TRUE, |
|
dwFlags, // flags |
|
NULL, // environment |
|
launchDirectory, // current directory |
|
&si, |
|
&pi ) ) |
|
{ |
|
::MessageBoxA( NULL, GetLastWindowsErrorString(), "Error", MB_OK | MB_ICONINFORMATION | MB_APPLMODAL ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
void CSDKLauncherDialog::OnCommand( const char *command ) |
|
{ |
|
if ( Q_stricmp( command, "LaunchButton" ) == 0 ) |
|
{ |
|
Launch( m_pMediaList->GetSelectedItem(), false ); |
|
} |
|
else if ( Q_stricmp( command, "ResetConfigs" ) == 0 ) |
|
{ |
|
ResetConfigs(); |
|
} |
|
else if ( Q_stricmp( command, "RefreshMinFootprint" ) == 0 ) |
|
{ |
|
DumpMinFootprintFiles( true ); |
|
} |
|
|
|
BaseClass::OnCommand( command ); |
|
} |
|
|
|
|
|
void CSDKLauncherDialog::OnItemDoubleLeftClick( int iItem ) |
|
{ |
|
Launch( iItem, false ); |
|
} |
|
|
|
|
|
void CSDKLauncherDialog::OnItemContextMenu( int hActiveListItem ) |
|
{ |
|
if (!m_pMediaList->IsItemIDValid(hActiveListItem)) |
|
return; |
|
|
|
// display the file |
|
KeyValues *item = m_pMediaList->GetItemData( hActiveListItem ); |
|
if ( !item ) |
|
return; |
|
|
|
// Build the context menu. |
|
m_pContextMenu->DeleteAllItems(); |
|
|
|
// Is this a ShellExecute or a program they want to run? |
|
const char *pStr = item->GetString( "ShellExecute", NULL ); |
|
if ( pStr ) |
|
m_pContextMenu->AddMenuItem( "RunGame", "Open In Web Browser", new KeyValues("ItemDoubleLeftClick", "itemID", hActiveListItem), this); |
|
else |
|
m_pContextMenu->AddMenuItem( "RunGame", "Launch", new KeyValues("ItemDoubleLeftClick", "itemID", hActiveListItem), this); |
|
|
|
int menuWide, menuTall; |
|
m_pContextMenu->SetVisible(true); |
|
m_pContextMenu->InvalidateLayout(true); |
|
m_pContextMenu->GetSize(menuWide, menuTall); |
|
|
|
// work out where the cursor is and therefore the best place to put the menu |
|
int wide, tall; |
|
surface()->GetScreenSize(wide, tall); |
|
|
|
int cx, cy; |
|
input()->GetCursorPos(cx, cy); |
|
|
|
if (wide - menuWide > cx) |
|
{ |
|
// menu hanging right |
|
if (tall - menuTall > cy) |
|
{ |
|
// menu hanging down |
|
m_pContextMenu->SetPos(cx, cy); |
|
} |
|
else |
|
{ |
|
// menu hanging up |
|
m_pContextMenu->SetPos(cx, cy - menuTall); |
|
} |
|
} |
|
else |
|
{ |
|
// menu hanging left |
|
if (tall - menuTall > cy) |
|
{ |
|
// menu hanging down |
|
m_pContextMenu->SetPos(cx - menuWide, cy); |
|
} |
|
else |
|
{ |
|
// menu hanging up |
|
m_pContextMenu->SetPos(cx - menuWide, cy - menuTall); |
|
} |
|
} |
|
|
|
m_pContextMenu->RequestFocus(); |
|
m_pContextMenu->MoveToFront(); |
|
} |
|
|
|
bool CSDKLauncherDialog::ParseConfigs( CUtlVector<CGameConfig*> &configs ) |
|
{ |
|
if ( !g_ConfigManager.IsLoaded() ) |
|
return false; |
|
|
|
// Find the games block of the keyvalues |
|
KeyValues *gameBlock = g_ConfigManager.GetGameBlock(); |
|
|
|
if ( gameBlock == NULL ) |
|
{ |
|
return false; |
|
} |
|
|
|
// Iterate through all subkeys |
|
for ( KeyValues *pGame=gameBlock->GetFirstTrueSubKey(); pGame; pGame=pGame->GetNextTrueSubKey() ) |
|
{ |
|
const char *pName = pGame->GetName(); |
|
const char *pDir = pGame->GetString( TOKEN_GAME_DIRECTORY ); |
|
|
|
CGameConfig *newConfig = new CGameConfig(); |
|
UtlStrcpy( newConfig->m_Name, pName ); |
|
UtlStrcpy( newConfig->m_ModDir, pDir ); |
|
|
|
configs.AddToTail( newConfig ); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
void CSDKLauncherDialog::PopulateCurrentEngineCombo( bool bSelectLast ) |
|
{ |
|
int nActiveEngine = 0; |
|
|
|
m_pCurrentEngineCombo->DeleteAllItems(); |
|
|
|
// Add ep1 engine |
|
KeyValues *kv = new KeyValues( "values" ); |
|
kv = new KeyValues( "values" ); |
|
kv->SetString( "EngineVer", "ep1" ); |
|
m_pCurrentEngineCombo->AddItem( "Source Engine 2006", kv ); |
|
kv->deleteThis(); |
|
if ( !V_strcmp( g_engineDir, "ep1" ) ) |
|
{ |
|
nActiveEngine = 0; |
|
} |
|
|
|
// Add ep2 engine |
|
kv = new KeyValues( "values" ); |
|
kv->SetString( "EngineVer", "source2007" ); |
|
m_pCurrentEngineCombo->AddItem( "Source Engine 2007", kv ); |
|
kv->deleteThis(); |
|
if ( !V_strcmp( g_engineDir, "source2007" ) ) |
|
{ |
|
nActiveEngine = 1; |
|
} |
|
|
|
// Add SP engine |
|
kv = new KeyValues( "values" ); |
|
kv->SetString( "EngineVer", "source2009" ); |
|
m_pCurrentEngineCombo->AddItem( "Source Engine 2009", kv ); |
|
kv->deleteThis(); |
|
if ( !V_strcmp( g_engineDir, "source2009" ) ) |
|
{ |
|
nActiveEngine = 2; |
|
} |
|
|
|
// Add MP engine |
|
kv = new KeyValues( "values" ); |
|
kv->SetString( "EngineVer", "orangebox" ); |
|
m_pCurrentEngineCombo->AddItem( "Source Engine MP", kv ); |
|
kv->deleteThis(); |
|
if ( !V_strcmp( g_engineDir, "orangebox" ) ) |
|
{ |
|
nActiveEngine = 3; |
|
} |
|
|
|
// Determine active configuration |
|
m_pCurrentEngineCombo->ActivateItem( nActiveEngine ); |
|
} |
|
|
|
void CSDKLauncherDialog::SetCurrentGame( const char* pcCurrentGame ) |
|
{ |
|
int activeConfig = -1; |
|
|
|
for ( int i=0; i < m_pCurrentGameCombo->GetItemCount(); i++ ) |
|
{ |
|
KeyValues *kv = m_pCurrentGameCombo->GetItemUserData( i ); |
|
|
|
// Check to see if this is our currently active game |
|
if ( Q_stricmp( kv->GetString( "ModDir" ), pcCurrentGame ) == 0 ) |
|
{ |
|
activeConfig = i; |
|
continue; |
|
} |
|
} |
|
|
|
if ( activeConfig > -1 ) |
|
{ |
|
// Activate our currently selected game |
|
m_pCurrentGameCombo->ActivateItem( activeConfig ); |
|
} |
|
else |
|
{ |
|
// If the VCONFIG value for the game is not found then repopulate |
|
PopulateCurrentGameCombo( false ); |
|
} |
|
} |
|
|
|
|
|
void CSDKLauncherDialog::PopulateCurrentGameCombo( bool bSelectLast ) |
|
{ |
|
m_pCurrentGameCombo->DeleteAllItems(); |
|
|
|
CUtlVector<CGameConfig*> configs; |
|
|
|
ParseConfigs( configs ); |
|
|
|
char szGame[MAX_PATH]; |
|
GetVConfigRegistrySetting( GAMEDIR_TOKEN, szGame, sizeof( szGame ) ); |
|
|
|
int activeConfig = -1; |
|
|
|
CUtlVector<int> itemIDs; |
|
itemIDs.SetSize( configs.Count() ); |
|
for ( int i=0; i < configs.Count(); i++ ) |
|
{ |
|
KeyValues *kv = new KeyValues( "values" ); |
|
kv->SetString( "ModDir", configs[i]->m_ModDir.Base() ); |
|
kv->SetPtr( "panel", m_pCurrentGameCombo ); |
|
|
|
|
|
// Check to see if this is our currently active game |
|
if ( Q_stricmp( configs[i]->m_ModDir.Base(), szGame ) == 0 ) |
|
{ |
|
activeConfig = i; |
|
} |
|
|
|
itemIDs[i] = m_pCurrentGameCombo->AddItem( configs[i]->m_Name.Base(), kv ); |
|
|
|
kv->deleteThis(); |
|
} |
|
|
|
// Activate the correct entry if valid |
|
if ( itemIDs.Count() > 0 ) |
|
{ |
|
m_pCurrentGameCombo->SetEnabled( true ); |
|
|
|
if ( bSelectLast ) |
|
{ |
|
m_pCurrentGameCombo->ActivateItem( itemIDs[itemIDs.Count()-1] ); |
|
} |
|
else |
|
{ |
|
if ( activeConfig > -1 ) |
|
{ |
|
// Activate our currently selected game |
|
m_pCurrentGameCombo->ActivateItem( activeConfig ); |
|
} |
|
else |
|
{ |
|
// Always default to the first otherwise |
|
m_pCurrentGameCombo->ActivateItem( 0 ); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
m_pCurrentGameCombo->SetEnabled( false ); |
|
} |
|
|
|
configs.PurgeAndDeleteElements(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Selection has changed in the active config drop-down, set the environment |
|
//----------------------------------------------------------------------------- |
|
void CSDKLauncherDialog::OnTextChanged( KeyValues *pkv ) |
|
{ |
|
const vgui::ComboBox* combo = (vgui::ComboBox*)pkv->GetPtr("panel"); |
|
|
|
if ( combo == m_pCurrentGameCombo) |
|
{ |
|
KeyValues *kv = m_pCurrentGameCombo->GetActiveItemUserData(); |
|
|
|
if ( kv ) |
|
{ |
|
const char *modDir = kv->GetString( "ModDir" ); |
|
SetVConfigRegistrySetting( GAMEDIR_TOKEN, modDir, true ); |
|
} |
|
} |
|
else if ( combo == m_pCurrentEngineCombo ) |
|
{ |
|
KeyValues *kv = m_pCurrentEngineCombo->GetActiveItemUserData(); |
|
|
|
if ( kv ) |
|
{ |
|
const char *engineDir = kv->GetString( "EngineVer" ); |
|
SetEngineVersion( engineDir ); |
|
RefreshConfigs(); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Refresh our configs after a file change outside our process |
|
//----------------------------------------------------------------------------- |
|
void CSDKLauncherDialog::RefreshConfigs( void ) |
|
{ |
|
char szGameConfigDir[MAX_PATH]; |
|
|
|
V_strcpy_safe( szGameConfigDir, GetSDKLauncherBinDirectory() ); |
|
V_AppendSlash( szGameConfigDir, MAX_PATH ); |
|
V_strncat( szGameConfigDir, g_engineDir, MAX_PATH ); |
|
V_AppendSlash( szGameConfigDir, MAX_PATH ); |
|
V_strncat( szGameConfigDir, "bin", MAX_PATH ); |
|
|
|
// Set directory in which GameConfig.txt is found |
|
g_ConfigManager.SetBaseDirectory( szGameConfigDir ); |
|
|
|
// Tell the config manager which games to put in the config by default |
|
if ( !stricmp( g_engineDir, "ep1" ) ) |
|
{ |
|
g_ConfigManager.SetSDKEpoch( EP1 ); |
|
} |
|
else if ( !stricmp( g_engineDir, "source2007" ) ) |
|
{ |
|
g_ConfigManager.SetSDKEpoch( EP2 ); |
|
} |
|
else if ( !stricmp( g_engineDir, "source2009" ) ) |
|
{ |
|
g_ConfigManager.SetSDKEpoch( SP2009 ); |
|
} |
|
else |
|
{ |
|
g_ConfigManager.SetSDKEpoch( MP2009 ); |
|
} |
|
|
|
|
|
// Load configurations |
|
if ( g_ConfigManager.LoadConfigs( szGameConfigDir ) == false ) |
|
{ |
|
m_pCurrentGameCombo->DeleteAllItems(); |
|
m_pCurrentGameCombo->SetEnabled( false ); |
|
} |
|
else |
|
{ |
|
m_pCurrentGameCombo->SetEnabled( true ); |
|
|
|
if ( g_ConfigManager.WasConvertedOnLoad() ) |
|
{ |
|
// Notify of a conversion |
|
CConversionInfoMessageBox *pDlg = new CConversionInfoMessageBox( this, "ConversionInfo" ); |
|
|
|
pDlg->RequestFocus(); |
|
pDlg->SetVisible( true ); |
|
pDlg->MoveToCenterOfScreen(); |
|
input()->SetAppModalSurface( pDlg->GetVPanel() ); |
|
} |
|
} |
|
|
|
// Dump the current settings and reparse the change |
|
PopulateCurrentGameCombo( false ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Reset our config files |
|
//----------------------------------------------------------------------------- |
|
void CSDKLauncherDialog::ResetConfigs( void ) |
|
{ |
|
// Reset the configs |
|
g_ConfigManager.ResetConfigs(); |
|
|
|
// Refresh the listing |
|
PopulateCurrentGameCombo( false ); |
|
|
|
// Notify the user |
|
VGUIMessageBox( this, "Complete", "Your game configurations have successfully been reset to their default values." ); |
|
} |
|
|
|
void CSDKLauncherDialog::GetEngineVersion(char* pcEngineVer, int nSize) |
|
{ |
|
IRegistry *reg = InstanceRegistry( "Source SDK" ); |
|
Assert( reg ); |
|
V_strncpy( pcEngineVer, reg->ReadString( "EngineVer", "orangebox" ), nSize ); |
|
ReleaseInstancedRegistry( reg ); |
|
} |
|
|
|
void CSDKLauncherDialog::SetEngineVersion(const char *pcEngineVer) |
|
{ |
|
IRegistry *reg = InstanceRegistry( "Source SDK" ); |
|
Assert( reg ); |
|
reg->WriteString( "EngineVer", pcEngineVer ); |
|
ReleaseInstancedRegistry( reg ); |
|
|
|
// Set the global to the same value as the registry |
|
V_strncpy( g_engineDir, pcEngineVer, sizeof( g_engineDir ) ); |
|
} |