Team Fortress 2 Source Code as on 22/4/2020
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.

1890 lines
53 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #if defined( WIN32 ) && !defined( _X360 )
  8. #include <windows.h> // SRC only!!
  9. #endif
  10. #include "OptionsSubMultiplayer.h"
  11. #include "MultiplayerAdvancedDialog.h"
  12. #include <stdio.h>
  13. #include <vgui_controls/Button.h>
  14. #include <vgui_controls/QueryBox.h>
  15. #include <vgui_controls/CheckButton.h>
  16. #include "tier1/KeyValues.h"
  17. #include <vgui_controls/Label.h>
  18. #include <vgui/ISystem.h>
  19. #include <vgui/ISurface.h>
  20. #include <vgui/Cursor.h>
  21. #include <vgui_controls/RadioButton.h>
  22. #include <vgui_controls/ComboBox.h>
  23. #include <vgui_controls/ImagePanel.h>
  24. #include <vgui_controls/FileOpenDialog.h>
  25. #include <vgui_controls/MessageBox.h>
  26. #include <vgui/IVGui.h>
  27. #include <vgui/ILocalize.h>
  28. #include <vgui/IPanel.h>
  29. #include <vgui_controls/MessageBox.h>
  30. #include "CvarTextEntry.h"
  31. #include "CvarToggleCheckButton.h"
  32. #include "cvarslider.h"
  33. #include "LabeledCommandComboBox.h"
  34. #include "filesystem.h"
  35. #include "EngineInterface.h"
  36. #include "BitmapImagePanel.h"
  37. #include "tier1/utlbuffer.h"
  38. #include "ModInfo.h"
  39. #include "tier1/convar.h"
  40. #include "tier0/icommandline.h"
  41. #include "materialsystem/imaterial.h"
  42. #include "materialsystem/imesh.h"
  43. #include "materialsystem/imaterialvar.h"
  44. // use the JPEGLIB_USE_STDIO define so that we can read in jpeg's from outside the game directory tree. For Spray Import.
  45. #define JPEGLIB_USE_STDIO
  46. #include "jpeglib/jpeglib.h"
  47. #undef JPEGLIB_USE_STDIO
  48. #include <setjmp.h>
  49. #include "bitmap/tgawriter.h"
  50. #include "ivtex.h"
  51. #ifdef WIN32
  52. #include <io.h>
  53. #endif
  54. #if defined( _X360 )
  55. #include "xbox/xbox_win32stubs.h"
  56. #endif
  57. // memdbgon must be the last include file in a .cpp file!!!
  58. #include <tier0/memdbgon.h>
  59. using namespace vgui;
  60. #define DEFAULT_SUIT_HUE 30
  61. #define DEFAULT_PLATE_HUE 6
  62. void UpdateLogoWAD( void *hdib, int r, int g, int b );
  63. struct ColorItem_t
  64. {
  65. const char *name;
  66. int r, g, b;
  67. };
  68. static ColorItem_t itemlist[]=
  69. {
  70. { "#Valve_Orange", 255, 120, 24 },
  71. { "#Valve_Yellow", 225, 180, 24 },
  72. { "#Valve_Blue", 0, 60, 255 },
  73. { "#Valve_Ltblue", 0, 167, 255 },
  74. { "#Valve_Green", 0, 167, 0 },
  75. { "#Valve_Red", 255, 43, 0 },
  76. { "#Valve_Brown", 123, 73, 0 },
  77. { "#Valve_Ltgray", 100, 100, 100 },
  78. { "#Valve_Dkgray", 36, 36, 36 },
  79. };
  80. static ColorItem_t s_crosshairColors[] =
  81. {
  82. { "#Valve_Green", 50, 250, 50 },
  83. { "#Valve_Red", 250, 50, 50 },
  84. { "#Valve_Blue", 50, 50, 250 },
  85. { "#Valve_Yellow", 250, 250, 50 },
  86. { "#Valve_Ltblue", 50, 250, 250 },
  87. };
  88. static const int NumCrosshairColors = ARRAYSIZE(s_crosshairColors);
  89. //-----------------------------------------------------------------------------
  90. class CrosshairImagePanelSimple : public CrosshairImagePanelBase
  91. {
  92. DECLARE_CLASS_SIMPLE( CrosshairImagePanelSimple, CrosshairImagePanelBase );
  93. public:
  94. CrosshairImagePanelSimple( Panel *parent, const char *name, COptionsSubMultiplayer* pOptionsPanel );
  95. virtual void Paint();
  96. virtual void ResetData();
  97. virtual void ApplyChanges();
  98. static void DrawCrosshairRect( int x, int y, int w, int h, bool bAdditive );
  99. protected:
  100. MESSAGE_FUNC_PTR( OnTextChanged, "TextChanged", panel );
  101. void InitCrosshairColorEntries();
  102. void InitCrosshairSizeList();
  103. void UpdateCrosshair();
  104. private:
  105. COptionsSubMultiplayer* m_pOptionsPanel;
  106. vgui::ComboBox *m_pCrosshairColorCombo;
  107. CLabeledCommandComboBox *m_pCrosshairSizeCombo;
  108. CCvarToggleCheckButton *m_pCrosshairTranslucencyCheckbox;
  109. int m_R, m_G, m_B;
  110. int m_barSize;
  111. int m_barGap;
  112. int m_iCrosshairTextureID;
  113. };
  114. //-----------------------------------------------------------------------------
  115. CrosshairImagePanelSimple::CrosshairImagePanelSimple( Panel *parent, const char *name, COptionsSubMultiplayer* pOptionsPanel ) : CrosshairImagePanelBase( parent, name )
  116. {
  117. m_pOptionsPanel = pOptionsPanel;
  118. m_pCrosshairTranslucencyCheckbox = new CCvarToggleCheckButton(m_pOptionsPanel, "CrosshairTranslucencyCheckbox", "#GameUI_Translucent", "cl_crosshairusealpha");
  119. m_pCrosshairColorCombo = new ComboBox(m_pOptionsPanel, "CrosshairColorComboBox", 6, false);
  120. m_pCrosshairSizeCombo = new CLabeledCommandComboBox(m_pOptionsPanel, "CrosshairSizeComboBox");
  121. m_pCrosshairColorCombo->AddActionSignalTarget( this );
  122. m_pCrosshairSizeCombo->AddActionSignalTarget( this );
  123. m_iCrosshairTextureID = vgui::surface()->CreateNewTextureID();
  124. vgui::surface()->DrawSetTextureFile( m_iCrosshairTextureID, "vgui/white_additive" , true, false);
  125. InitCrosshairSizeList();
  126. InitCrosshairColorEntries();
  127. ResetData();
  128. }
  129. //-----------------------------------------------------------------------------
  130. // Purpose: initialize the crosshair size list.
  131. //-----------------------------------------------------------------------------
  132. void CrosshairImagePanelSimple::InitCrosshairSizeList()
  133. {
  134. // add in the auto, small, medium, and large size selections.
  135. m_pCrosshairSizeCombo->AddItem("#GameUI_Auto", "cl_crosshairscale 0");
  136. m_pCrosshairSizeCombo->AddItem("#GameUI_Small", "cl_crosshairscale 1200");
  137. m_pCrosshairSizeCombo->AddItem("#GameUI_Medium", "cl_crosshairscale 768");
  138. m_pCrosshairSizeCombo->AddItem("#GameUI_Large", "cl_crosshairscale 600");
  139. }
  140. //-----------------------------------------------------------------------------
  141. // Purpose:
  142. //-----------------------------------------------------------------------------
  143. void CrosshairImagePanelSimple::InitCrosshairColorEntries()
  144. {
  145. if (m_pCrosshairColorCombo != NULL)
  146. {
  147. KeyValues *data = new KeyValues("data");
  148. // add in the "Default" selection
  149. data->Clear();
  150. // add in the colors for the color list
  151. for ( int i = 0; i < NumCrosshairColors; i++ )
  152. {
  153. data->SetInt("color", i);
  154. m_pCrosshairColorCombo->AddItem( s_crosshairColors[ i ].name, data);
  155. }
  156. data->deleteThis();
  157. }
  158. }
  159. //-----------------------------------------------------------------------------
  160. void CrosshairImagePanelSimple::DrawCrosshairRect( int x0, int y0, int x1, int y1, bool bAdditive )
  161. {
  162. if ( bAdditive )
  163. vgui::surface()->DrawTexturedRect( x0, y0, x1, y1 );
  164. else
  165. vgui::surface()->DrawFilledRect( x0, y0, x1, y1 );
  166. }
  167. //-----------------------------------------------------------------------------
  168. void CrosshairImagePanelSimple::Paint()
  169. {
  170. int screenWide, screenTall;
  171. surface()->GetScreenSize( screenWide, screenTall );;
  172. BaseClass::Paint();
  173. if ( !m_pCrosshairTranslucencyCheckbox )
  174. return;
  175. int wide, tall;
  176. GetSize( wide, tall );
  177. bool bAdditive = !m_pCrosshairTranslucencyCheckbox->IsSelected();
  178. int a = 200;
  179. ConVarRef cl_crosshairalpha( "cl_crosshairalpha", true );
  180. if ( !bAdditive && cl_crosshairalpha.IsValid() )
  181. {
  182. a = clamp( cl_crosshairalpha.GetInt(), 0, 255 );
  183. }
  184. vgui::surface()->DrawSetColor( m_R, m_G, m_B, a );
  185. if ( bAdditive )
  186. {
  187. vgui::surface()->DrawSetTexture( m_iCrosshairTextureID );
  188. }
  189. int centerX = wide / 2;
  190. int centerY = tall / 2;
  191. int iCrosshairDistance = m_barGap;
  192. int iBarThickness = 1;
  193. int iBarSize = m_barSize;
  194. // draw horizontal crosshair lines
  195. int iInnerLeft = centerX - iCrosshairDistance - iBarThickness / 2;
  196. int iInnerRight = iInnerLeft + 2 * iCrosshairDistance + iBarThickness;
  197. int iOuterLeft = iInnerLeft - iBarSize;
  198. int iOuterRight = iInnerRight + iBarSize;
  199. int y0 = centerY - iBarThickness / 2;
  200. int y1 = y0 + iBarThickness;
  201. DrawCrosshairRect( iOuterLeft, y0, iInnerLeft, y1, bAdditive );
  202. DrawCrosshairRect( iInnerRight, y0, iOuterRight, y1, bAdditive );
  203. // draw vertical crosshair lines
  204. int iInnerTop = centerY - iCrosshairDistance - iBarThickness / 2;
  205. int iInnerBottom = iInnerTop + 2 * iCrosshairDistance + iBarThickness;
  206. int iOuterTop = iInnerTop - iBarSize;
  207. int iOuterBottom = iInnerBottom + iBarSize;
  208. int x0 = centerX - iBarThickness / 2;
  209. int x1 = x0 + iBarThickness;
  210. DrawCrosshairRect( x0, iOuterTop, x1, iInnerTop, bAdditive );
  211. DrawCrosshairRect( x0, iInnerBottom, x1, iOuterBottom, bAdditive );
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Purpose: takes the settings from the crosshair settings combo boxes and sliders
  215. // and apply it to the crosshair illustrations.
  216. //-----------------------------------------------------------------------------
  217. void CrosshairImagePanelSimple::UpdateCrosshair()
  218. {
  219. // get the color selected in the combo box.
  220. KeyValues *data = m_pCrosshairColorCombo->GetActiveItemUserData();
  221. int colorIndex = data->GetInt("color");
  222. colorIndex = clamp( colorIndex, 0, NumCrosshairColors );
  223. int selectedColor = 0;
  224. int actualVal = 0;
  225. if (m_pCrosshairColorCombo != NULL)
  226. {
  227. selectedColor = m_pCrosshairColorCombo->GetActiveItem();
  228. }
  229. ConVarRef cl_crosshaircolor( "cl_crosshaircolor", true );
  230. if ( cl_crosshaircolor.IsValid() )
  231. {
  232. actualVal = clamp( cl_crosshaircolor.GetInt(), 0, NumCrosshairColors );
  233. }
  234. m_R = s_crosshairColors[selectedColor].r;
  235. m_G = s_crosshairColors[selectedColor].g;
  236. m_B = s_crosshairColors[selectedColor].b;
  237. if ( m_pCrosshairSizeCombo )
  238. {
  239. int size = m_pCrosshairSizeCombo->GetActiveItem();
  240. if ( size == 0 )
  241. {
  242. int screenWide, screenTall;
  243. surface()->GetScreenSize( screenWide, screenTall );
  244. if ( screenTall <= 600 )
  245. {
  246. // if the screen height is 600 or less, set the crosshair num to 3 (large)
  247. size = 3;
  248. }
  249. else if ( screenTall <= 768 )
  250. {
  251. // if the screen height is between 600 and 768, set the crosshair num to 2 (medium)
  252. size = 2;
  253. }
  254. else
  255. {
  256. // if the screen height is greater than 768, set the crosshair num to 1 (small)
  257. size = 1;
  258. }
  259. }
  260. int scaleBase;
  261. switch( size )
  262. {
  263. case 1:
  264. scaleBase = 1200;
  265. break;
  266. case 2:
  267. scaleBase = 768;
  268. break;
  269. case 3:
  270. scaleBase = 600;
  271. break;
  272. default:
  273. scaleBase = 1200;
  274. break;
  275. }
  276. m_barSize = (int) 9 * 1200 / scaleBase;
  277. m_barGap = (int) 5 * 1200 / scaleBase;
  278. }
  279. }
  280. //-----------------------------------------------------------------------------
  281. // Purpose: Called whenever color combo changes
  282. //-----------------------------------------------------------------------------
  283. void CrosshairImagePanelSimple::OnTextChanged(vgui::Panel *panel)
  284. {
  285. m_pOptionsPanel->OnControlModified();
  286. UpdateCrosshair();
  287. }
  288. void CrosshairImagePanelSimple::ResetData()
  289. {
  290. m_pCrosshairTranslucencyCheckbox->Reset();
  291. // parse out the size value from the cvar and set the initial value.
  292. int initialScale = 0;
  293. ConVarRef cl_crosshairscale( "cl_crosshairscale", true );
  294. if ( cl_crosshairscale.IsValid() )
  295. {
  296. initialScale = cl_crosshairscale.GetInt();
  297. if ( initialScale <= 0 )
  298. {
  299. initialScale = 0;
  300. }
  301. else if ( initialScale <= 600 )
  302. {
  303. initialScale = 3;
  304. }
  305. else if ( initialScale <= 768 )
  306. {
  307. initialScale = 2;
  308. }
  309. else
  310. {
  311. initialScale = 1;
  312. }
  313. }
  314. m_pCrosshairSizeCombo->SetInitialItem( initialScale );
  315. // parse the string for the custom color settings and get the initial settings.
  316. ConVarRef cl_crosshaircolor( "cl_crosshaircolor", true );
  317. int index = 0;
  318. if ( cl_crosshaircolor.IsValid() )
  319. {
  320. index = clamp( cl_crosshaircolor.GetInt(), 0, NumCrosshairColors );
  321. }
  322. m_pCrosshairColorCombo->ActivateItemByRow(index);
  323. UpdateCrosshair();
  324. }
  325. void CrosshairImagePanelSimple::ApplyChanges()
  326. {
  327. m_pCrosshairTranslucencyCheckbox->ApplyChanges();
  328. char cmd[256];
  329. cmd[0] = 0;
  330. if (m_pCrosshairColorCombo != NULL)
  331. {
  332. int val = m_pCrosshairColorCombo->GetActiveItem();
  333. Q_snprintf( cmd, sizeof(cmd), "cl_crosshaircolor %d\n", val );
  334. engine->ClientCmd_Unrestricted( cmd );
  335. }
  336. }
  337. //-----------------------------------------------------------------------------
  338. class CrosshairImagePanelCS : public CrosshairImagePanelBase
  339. {
  340. DECLARE_CLASS_SIMPLE( CrosshairImagePanelCS, CrosshairImagePanelBase );
  341. public:
  342. CrosshairImagePanelCS( Panel *parent, const char *name, COptionsSubMultiplayer* pOptionsPanel );
  343. virtual void ResetData();
  344. virtual void ApplyChanges();
  345. protected:
  346. MESSAGE_FUNC_PARAMS( OnSliderMoved, "SliderMoved", data );
  347. MESSAGE_FUNC_PTR( OnTextChanged, "TextChanged", panel );
  348. MESSAGE_FUNC( OnCheckButtonChecked, "CheckButtonChecked" );
  349. virtual void Paint();
  350. static void DrawCrosshairRect( int x, int y, int w, int h, bool bAdditive );
  351. void InitCrosshairColorEntries();
  352. void UpdateCrosshair();
  353. private:
  354. COptionsSubMultiplayer* m_pOptionsPanel;
  355. vgui::ComboBox *m_pColorComboBox;
  356. CCvarToggleCheckButton *m_pAlphaCheckbox;
  357. CCvarToggleCheckButton *m_pDynamicCheckbox;
  358. CCvarToggleCheckButton *m_pDotCheckbox;
  359. CCvarSlider *m_pColorAlphaSlider;
  360. CCvarSlider *m_pColorRSlider;
  361. CCvarSlider *m_pColorGSlider;
  362. CCvarSlider *m_pColorBSlider;
  363. CCvarSlider *m_pSizeSlider;
  364. CCvarSlider *m_pThicknessSlider;
  365. int m_R, m_G, m_B;
  366. float m_barSize;
  367. float m_barThickness;
  368. int m_iCrosshairTextureID;
  369. };
  370. //-----------------------------------------------------------------------------
  371. CrosshairImagePanelCS::CrosshairImagePanelCS( Panel *parent, const char *name, COptionsSubMultiplayer* pOptionsPanel ) : CrosshairImagePanelBase( parent, name )
  372. {
  373. m_pOptionsPanel = pOptionsPanel;
  374. m_pColorComboBox = new ComboBox(m_pOptionsPanel, "CrosshairColorComboBox", 6, false);
  375. m_pAlphaCheckbox = new CCvarToggleCheckButton(m_pOptionsPanel, "CrosshairTranslucencyCheckbox", "#GameUI_Crosshair_Blend", "cl_crosshairusealpha");
  376. m_pDynamicCheckbox = new CCvarToggleCheckButton(m_pOptionsPanel, "CrosshairDynamicCheckbox", "#GameUI_CrosshairDynamic", "cl_dynamiccrosshair");
  377. m_pDotCheckbox = new CCvarToggleCheckButton(m_pOptionsPanel, "CrosshairDotCheckbox", "#GameUI_CrosshairDot", "cl_crosshairdot");
  378. m_pColorAlphaSlider = new CCvarSlider( m_pOptionsPanel, "Alpha Slider", "#GameUI_CrosshairColor_Alpha",
  379. 0.0f, 255.0f, "cl_crosshairalpha" );
  380. m_pColorRSlider = new CCvarSlider( m_pOptionsPanel, "Red Color Slider", "#GameUI_CrosshairColor_Red",
  381. 0.0f, 255.0f, "cl_crosshaircolor_r" );
  382. m_pColorGSlider = new CCvarSlider( m_pOptionsPanel, "Green Color Slider", "#GameUI_CrosshairColor_Green",
  383. 0.0f, 255.0f, "cl_crosshaircolor_g" );
  384. m_pColorBSlider = new CCvarSlider( m_pOptionsPanel, "Blue Color Slider", "#GameUI_CrosshairColor_Blue",
  385. 0.0f, 255.0f, "cl_crosshaircolor_b" );
  386. m_pSizeSlider = new CCvarSlider( m_pOptionsPanel, "Size Slider", "#GameUI_Crosshair_Size",
  387. 0.0f, 12.0f, "cl_crosshairsize" );
  388. m_pThicknessSlider = new CCvarSlider( m_pOptionsPanel, "Thickness Slider", "#GameUI_Crosshair_Thickness",
  389. 0.0f, 3.0f, "cl_crosshairthickness" );
  390. m_pColorAlphaSlider->SetTickCaptions("", "");
  391. m_pColorRSlider->SetTickCaptions("", "");
  392. m_pColorGSlider->SetTickCaptions("", "");
  393. m_pColorBSlider->SetTickCaptions("", "");
  394. m_pSizeSlider->SetTickCaptions("", "");
  395. m_pThicknessSlider->SetTickCaptions("", "");
  396. m_pAlphaCheckbox->AddActionSignalTarget(this);
  397. m_pDynamicCheckbox->AddActionSignalTarget(this);
  398. m_pDotCheckbox->AddActionSignalTarget(this);
  399. m_pColorComboBox->AddActionSignalTarget( this );
  400. m_pColorAlphaSlider->AddActionSignalTarget( this );
  401. m_pColorRSlider->AddActionSignalTarget( this );
  402. m_pColorGSlider->AddActionSignalTarget( this );
  403. m_pColorBSlider->AddActionSignalTarget( this );
  404. m_pSizeSlider->AddActionSignalTarget( this );
  405. m_pThicknessSlider->AddActionSignalTarget( this );
  406. InitCrosshairColorEntries();
  407. m_iCrosshairTextureID = vgui::surface()->CreateNewTextureID();
  408. vgui::surface()->DrawSetTextureFile( m_iCrosshairTextureID, "vgui/white_additive" , true, false);
  409. ResetData();
  410. }
  411. void CrosshairImagePanelCS::InitCrosshairColorEntries()
  412. {
  413. if (m_pColorComboBox != NULL)
  414. {
  415. KeyValues *data = new KeyValues("data");
  416. // add in the "Default" selection
  417. data->Clear();
  418. // add in the colors for the color list
  419. for ( int i = 0; i < NumCrosshairColors; i++ )
  420. {
  421. data->SetInt("color", i);
  422. m_pColorComboBox->AddItem( s_crosshairColors[ i ].name, data);
  423. }
  424. data->SetInt("color", NumCrosshairColors);
  425. m_pColorComboBox->AddItem( "Custom", data);
  426. data->deleteThis();
  427. }
  428. }
  429. //-----------------------------------------------------------------------------
  430. void CrosshairImagePanelCS::DrawCrosshairRect( int x0, int y0, int x1, int y1, bool bAdditive )
  431. {
  432. if ( bAdditive )
  433. vgui::surface()->DrawTexturedRect( x0, y0, x1, y1 );
  434. else
  435. vgui::surface()->DrawFilledRect( x0, y0, x1, y1 );
  436. }
  437. //-----------------------------------------------------------------------------
  438. void CrosshairImagePanelCS::Paint()
  439. {
  440. int screenWide, screenTall;
  441. surface()->GetScreenSize( screenWide, screenTall );;
  442. BaseClass::Paint();
  443. int wide, tall;
  444. GetSize( wide, tall );
  445. bool bAdditive = !m_pAlphaCheckbox->IsSelected();
  446. bool bDynamic = m_pDynamicCheckbox->IsSelected();
  447. int a = 255;
  448. if ( !bAdditive )
  449. a = m_pColorAlphaSlider->GetSliderValue();
  450. vgui::surface()->DrawSetColor( m_R, m_G, m_B, a );
  451. if ( bAdditive )
  452. {
  453. vgui::surface()->DrawSetTexture( m_iCrosshairTextureID );
  454. }
  455. int centerX = wide / 2;
  456. int centerY = tall / 2;
  457. int iBarSize = RoundFloatToInt(m_barSize * screenTall / 480.0f);
  458. int iBarThickness = max(1, RoundFloatToInt(m_barThickness * (float)screenTall / 480.0f));
  459. float fBarGap = 4.0f;
  460. if ( bDynamic )
  461. {
  462. float curtime = system()->GetFrameTime();
  463. fBarGap *= (1.0f + cosf(curtime * 1.5f) * 0.5f);
  464. }
  465. int iBarGap = RoundFloatToInt(fBarGap * screenTall / 480.0f);
  466. // draw horizontal crosshair lines
  467. int iInnerLeft = centerX - iBarGap - iBarThickness / 2;
  468. int iInnerRight = iInnerLeft + 2 * iBarGap + iBarThickness;
  469. int iOuterLeft = iInnerLeft - iBarSize;
  470. int iOuterRight = iInnerRight + iBarSize;
  471. int y0 = centerY - iBarThickness / 2;
  472. int y1 = y0 + iBarThickness;
  473. DrawCrosshairRect( iOuterLeft, y0, iInnerLeft, y1, bAdditive );
  474. DrawCrosshairRect( iInnerRight, y0, iOuterRight, y1, bAdditive );
  475. // draw vertical crosshair lines
  476. int iInnerTop = centerY - iBarGap - iBarThickness / 2;
  477. int iInnerBottom = iInnerTop + 2 * iBarGap + iBarThickness;
  478. int iOuterTop = iInnerTop - iBarSize;
  479. int iOuterBottom = iInnerBottom + iBarSize;
  480. int x0 = centerX - iBarThickness / 2;
  481. int x1 = x0 + iBarThickness;
  482. DrawCrosshairRect( x0, iOuterTop, x1, iInnerTop, bAdditive );
  483. DrawCrosshairRect( x0, iInnerBottom, x1, iOuterBottom, bAdditive );
  484. // draw dot
  485. if ( m_pDotCheckbox->IsSelected() )
  486. {
  487. x0 = centerX - iBarThickness / 2;
  488. x1 = x0 + iBarThickness;
  489. y0 = centerY - iBarThickness / 2;
  490. y1 = y0 + iBarThickness;
  491. DrawCrosshairRect( x0, y0, x1, y1, bAdditive );
  492. }
  493. }
  494. //-----------------------------------------------------------------------------
  495. // Purpose: takes the settings from the crosshair settings combo boxes and sliders
  496. // and apply it to the crosshair illustrations.
  497. //-----------------------------------------------------------------------------
  498. void CrosshairImagePanelCS::UpdateCrosshair()
  499. {
  500. // get the color selected in the combo box.
  501. KeyValues *data = m_pColorComboBox->GetActiveItemUserData();
  502. int colorIndex = data->GetInt("color");
  503. colorIndex = clamp( colorIndex, 0, NumCrosshairColors + 1 );
  504. int actualVal = 0;
  505. int selectedColor = m_pColorComboBox->GetActiveItem();
  506. ConVarRef cl_crosshaircolor( "cl_crosshaircolor", true );
  507. if ( cl_crosshaircolor.IsValid() )
  508. {
  509. actualVal = clamp( cl_crosshaircolor.GetInt(), 0, NumCrosshairColors + 1 );
  510. }
  511. if ( selectedColor != NumCrosshairColors ) // not custom
  512. {
  513. m_R = s_crosshairColors[selectedColor].r;
  514. m_G = s_crosshairColors[selectedColor].g;
  515. m_B = s_crosshairColors[selectedColor].b;
  516. m_pColorRSlider->SetSliderValue(m_R);
  517. m_pColorGSlider->SetSliderValue(m_G);
  518. m_pColorBSlider->SetSliderValue(m_B);
  519. }
  520. else
  521. {
  522. m_R = clamp( m_pColorRSlider->GetSliderValue(), 0, 255 );
  523. m_G = clamp( m_pColorGSlider->GetSliderValue(), 0, 255 );
  524. m_B = clamp( m_pColorBSlider->GetSliderValue(), 0, 255 );
  525. }
  526. m_barSize = m_pSizeSlider->GetSliderValue();
  527. m_barThickness = m_pThicknessSlider->GetSliderValue();
  528. }
  529. void CrosshairImagePanelCS::OnSliderMoved(KeyValues *data)
  530. {
  531. vgui::Panel* pPanel = static_cast<vgui::Panel*>(data->GetPtr("panel"));
  532. if ( pPanel == m_pColorRSlider || pPanel == m_pColorGSlider || pPanel == m_pColorBSlider )
  533. {
  534. m_pColorComboBox->ActivateItem(NumCrosshairColors);
  535. }
  536. m_pOptionsPanel->OnControlModified();
  537. UpdateCrosshair();
  538. }
  539. //-----------------------------------------------------------------------------
  540. // Purpose: Called whenever color combo changes
  541. //-----------------------------------------------------------------------------
  542. void CrosshairImagePanelCS::OnTextChanged(vgui::Panel *panel)
  543. {
  544. m_pOptionsPanel->OnControlModified();
  545. UpdateCrosshair();
  546. }
  547. void CrosshairImagePanelCS::OnCheckButtonChecked()
  548. {
  549. m_pColorAlphaSlider->SetEnabled(m_pAlphaCheckbox->IsSelected());
  550. m_pOptionsPanel->OnControlModified();
  551. UpdateCrosshair();
  552. }
  553. void CrosshairImagePanelCS::ResetData()
  554. {
  555. // parse the string for the custom color settings and get the initial settings.
  556. ConVarRef cl_crosshaircolor( "cl_crosshaircolor", true );
  557. int index = 0;
  558. if ( cl_crosshaircolor.IsValid() )
  559. {
  560. index = clamp( cl_crosshaircolor.GetInt(), 0, NumCrosshairColors + 1);
  561. }
  562. m_pColorComboBox->ActivateItemByRow(index);
  563. m_pAlphaCheckbox->Reset();
  564. m_pDynamicCheckbox->Reset();
  565. m_pDotCheckbox->Reset();
  566. m_pColorRSlider->Reset();
  567. m_pColorGSlider->Reset();
  568. m_pColorBSlider->Reset();
  569. m_pColorAlphaSlider->Reset();
  570. m_pSizeSlider->Reset();
  571. m_pThicknessSlider->Reset();
  572. UpdateCrosshair();
  573. }
  574. void CrosshairImagePanelCS::ApplyChanges()
  575. {
  576. m_pAlphaCheckbox->ApplyChanges();
  577. m_pDynamicCheckbox->ApplyChanges();
  578. m_pDotCheckbox->ApplyChanges();
  579. m_pColorRSlider->ApplyChanges();
  580. m_pColorGSlider->ApplyChanges();
  581. m_pColorBSlider->ApplyChanges();
  582. m_pColorAlphaSlider->ApplyChanges();
  583. m_pSizeSlider->ApplyChanges();
  584. m_pThicknessSlider->ApplyChanges();
  585. char cmd[256];
  586. cmd[0] = 0;
  587. if (m_pColorComboBox != NULL)
  588. {
  589. int val = m_pColorComboBox->GetActiveItem();
  590. Q_snprintf( cmd, sizeof(cmd), "cl_crosshaircolor %d\n", val );
  591. engine->ClientCmd_Unrestricted( cmd );
  592. }
  593. }
  594. //-----------------------------------------------------------------------------
  595. class CrosshairImagePanelAdvanced : public CrosshairImagePanelBase
  596. {
  597. DECLARE_CLASS_SIMPLE( CrosshairImagePanelAdvanced, CrosshairImagePanelBase );
  598. public:
  599. CrosshairImagePanelAdvanced( Panel *parent, const char *name, COptionsSubMultiplayer* pOptionsPanel );
  600. virtual ~CrosshairImagePanelAdvanced();
  601. virtual void ResetData();
  602. virtual void ApplyChanges();
  603. virtual void UpdateVisibility();
  604. protected:
  605. MESSAGE_FUNC_PTR( OnTextChanged, "TextChanged", panel );
  606. MESSAGE_FUNC_PARAMS( OnSliderMoved, "SliderMoved", data );
  607. virtual void Paint();
  608. static void DrawCrosshairRect( int x, int y, int w, int h, bool bAdditive );
  609. void InitAdvCrosshairStyleList();
  610. void SetCrosshairTexture( const char *crosshairname );
  611. void UpdateCrosshair();
  612. private:
  613. COptionsSubMultiplayer* m_pOptionsPanel;
  614. // --- advanced crosshair controls
  615. CCvarSlider *m_pAdvCrosshairRedSlider;
  616. CCvarSlider *m_pAdvCrosshairBlueSlider;
  617. CCvarSlider *m_pAdvCrosshairGreenSlider;
  618. CCvarSlider *m_pAdvCrosshairScaleSlider;
  619. CLabeledCommandComboBox *m_pAdvCrosshairStyle;
  620. int m_R, m_G, m_B;
  621. float m_flScale;
  622. // material
  623. int m_iCrosshairTextureID;
  624. IVguiMatInfo *m_pAdvCrosshairMaterial;
  625. // animation
  626. IVguiMatInfoVar *m_pFrameVar;
  627. float m_flNextFrameChange;
  628. int m_nNumFrames;
  629. bool m_bAscending; // animating forward or in reverse?
  630. };
  631. //-----------------------------------------------------------------------------
  632. CrosshairImagePanelAdvanced::CrosshairImagePanelAdvanced( Panel *parent, const char *name, COptionsSubMultiplayer* pOptionsPanel ) : CrosshairImagePanelBase( parent, name )
  633. {
  634. m_pOptionsPanel = pOptionsPanel;
  635. m_pAdvCrosshairMaterial = NULL;
  636. m_pFrameVar = NULL;
  637. m_pAdvCrosshairRedSlider = new CCvarSlider( pOptionsPanel, "Red Color Slider", "#GameUI_CrosshairColor_Red",
  638. 0.0f, 255.0f, "cl_crosshair_red" );
  639. m_pAdvCrosshairGreenSlider = new CCvarSlider( pOptionsPanel, "Green Color Slider", "#GameUI_CrosshairColor_Green",
  640. 0.0f, 255.0f, "cl_crosshair_green" );
  641. m_pAdvCrosshairBlueSlider = new CCvarSlider( pOptionsPanel, "Blue Color Slider", "#GameUI_CrosshairColor_Blue",
  642. 0.0f, 255.0f, "cl_crosshair_blue" );
  643. m_pAdvCrosshairRedSlider->SetTickCaptions("", "");
  644. m_pAdvCrosshairGreenSlider->SetTickCaptions("", "");
  645. m_pAdvCrosshairBlueSlider->SetTickCaptions("", "");
  646. m_pAdvCrosshairScaleSlider = new CCvarSlider( pOptionsPanel, "Scale Slider", "#GameUI_CrosshairScale",
  647. 16.0f, 48.0f, "cl_crosshair_scale" );
  648. m_pAdvCrosshairStyle = new CLabeledCommandComboBox( pOptionsPanel, "AdvCrosshairList" );
  649. m_pAdvCrosshairRedSlider->AddActionSignalTarget( this );
  650. m_pAdvCrosshairGreenSlider->AddActionSignalTarget( this );
  651. m_pAdvCrosshairBlueSlider->AddActionSignalTarget( this );
  652. m_pAdvCrosshairScaleSlider->AddActionSignalTarget( this );
  653. m_pAdvCrosshairStyle->AddActionSignalTarget(this);
  654. InitAdvCrosshairStyleList();
  655. m_iCrosshairTextureID = vgui::surface()->CreateNewTextureID();
  656. SetCrosshairTexture("vgui/crosshairs/crosshair1");
  657. UpdateCrosshair();
  658. }
  659. CrosshairImagePanelAdvanced::~CrosshairImagePanelAdvanced()
  660. {
  661. if ( m_pFrameVar )
  662. {
  663. delete m_pFrameVar;
  664. m_pFrameVar = NULL;
  665. }
  666. if ( m_pAdvCrosshairMaterial )
  667. {
  668. delete m_pAdvCrosshairMaterial;
  669. m_pAdvCrosshairMaterial = NULL;
  670. }
  671. }
  672. //-----------------------------------------------------------------------------
  673. void CrosshairImagePanelAdvanced::SetCrosshairTexture( const char *crosshairname )
  674. {
  675. if ( !crosshairname || !crosshairname[0] )
  676. {
  677. SetVisible( false );
  678. return;
  679. }
  680. SetVisible( true );
  681. vgui::surface()->DrawSetTextureFile( m_iCrosshairTextureID, crosshairname, true, false );
  682. if ( m_pAdvCrosshairMaterial )
  683. {
  684. delete m_pAdvCrosshairMaterial;
  685. }
  686. m_pAdvCrosshairMaterial = vgui::surface()->DrawGetTextureMatInfoFactory( m_iCrosshairTextureID );
  687. Assert(m_pAdvCrosshairMaterial);
  688. m_pFrameVar = m_pAdvCrosshairMaterial->FindVarFactory( "$frame", NULL );
  689. m_nNumFrames = m_pAdvCrosshairMaterial->GetNumAnimationFrames();
  690. m_flNextFrameChange = system()->GetFrameTime() + 0.2;
  691. m_bAscending = true;
  692. }
  693. //-----------------------------------------------------------------------------
  694. void CrosshairImagePanelAdvanced::Paint()
  695. {
  696. BaseClass::Paint();
  697. int wide, tall;
  698. GetSize( wide, tall );
  699. int iClipX0, iClipY0, iClipX1, iClipY1;
  700. ipanel()->GetClipRect(GetVPanel(), iClipX0, iClipY0, iClipX1, iClipY1 );
  701. // scroll through all frames
  702. if ( m_pFrameVar )
  703. {
  704. float curtime = system()->GetFrameTime();
  705. if ( curtime >= m_flNextFrameChange )
  706. {
  707. m_flNextFrameChange = curtime + 0.2;
  708. int frame = m_pFrameVar->GetIntValue();
  709. if ( m_bAscending )
  710. {
  711. frame++;
  712. if ( frame >= m_nNumFrames )
  713. {
  714. m_bAscending = !m_bAscending;
  715. frame--;
  716. }
  717. }
  718. else
  719. {
  720. frame--;
  721. if ( frame < 0 )
  722. {
  723. m_bAscending = !m_bAscending;
  724. frame++;
  725. }
  726. }
  727. m_pFrameVar->SetIntValue(frame);
  728. }
  729. }
  730. float x, y;
  731. // assume square
  732. float flDrawWidth = ( m_flScale/48.0 ) * (float)wide;
  733. int flHalfWidth = (int)( flDrawWidth / 2 );
  734. x = wide/2 - flHalfWidth;
  735. y = tall/2 - flHalfWidth;
  736. vgui::surface()->DrawSetColor( m_R, m_G, m_B, 255 );
  737. vgui::surface()->DrawSetTexture( m_iCrosshairTextureID );
  738. vgui::surface()->DrawTexturedRect( x, y, x+flDrawWidth, y+flDrawWidth );
  739. vgui::surface()->DrawSetTexture(0);
  740. }
  741. void CrosshairImagePanelAdvanced::UpdateCrosshair()
  742. {
  743. // get the color selected in the combo box.
  744. m_R = clamp( m_pAdvCrosshairRedSlider->GetSliderValue(), 0, 255 );
  745. m_G = clamp( m_pAdvCrosshairGreenSlider->GetSliderValue(), 0, 255 );
  746. m_B = clamp( m_pAdvCrosshairBlueSlider->GetSliderValue(), 0, 255 );
  747. m_flScale = m_pAdvCrosshairScaleSlider->GetSliderValue();
  748. if ( m_pAdvCrosshairStyle )
  749. {
  750. char crosshairname[256];
  751. m_pAdvCrosshairStyle->GetText( crosshairname, sizeof(crosshairname) );
  752. if ( ModInfo().AdvCrosshairLevel() == 1 && m_pAdvCrosshairStyle->GetActiveItem() == 0 ) // this is the "none" selection
  753. {
  754. SetCrosshairTexture(NULL);
  755. }
  756. else
  757. {
  758. char texture[ 256 ];
  759. Q_snprintf ( texture, sizeof( texture ), "vgui/crosshairs/%s", crosshairname );
  760. SetCrosshairTexture( texture );
  761. }
  762. }
  763. }
  764. //-----------------------------------------------------------------------------
  765. // Purpose: initialize the crosshair style list
  766. //-----------------------------------------------------------------------------
  767. void CrosshairImagePanelAdvanced::InitAdvCrosshairStyleList()
  768. {
  769. // Find out images
  770. FileFindHandle_t fh;
  771. char directory[ 512 ];
  772. ConVarRef cl_crosshair_file( "cl_crosshair_file", true );
  773. if ( !cl_crosshair_file.IsValid() )
  774. return;
  775. m_pAdvCrosshairStyle->DeleteAllItems();
  776. if ( ModInfo().AdvCrosshairLevel() == 1 )
  777. {
  778. m_pAdvCrosshairStyle->AddItem( "#GameUI_None", "" );
  779. }
  780. char crosshairfile[256];
  781. Q_snprintf( crosshairfile, sizeof(crosshairfile), "materials/vgui/crosshairs/%s.vtf", cl_crosshair_file.GetString() );
  782. Q_snprintf( directory, sizeof( directory ), "materials/vgui/crosshairs/*.vtf" );
  783. const char *fn = g_pFullFileSystem->FindFirst( directory, &fh );
  784. int i = 0, initialItem = 0;
  785. while (fn)
  786. {
  787. char filename[ 512 ];
  788. Q_snprintf( filename, sizeof(filename), "materials/vgui/crosshairs/%s", fn );
  789. if ( strlen( filename ) >= 4 )
  790. {
  791. filename[ strlen( filename ) - 4 ] = 0;
  792. Q_strncat( filename, ".vmt", sizeof( filename ), COPY_ALL_CHARACTERS );
  793. if ( g_pFullFileSystem->FileExists( filename ) )
  794. {
  795. // strip off the extension
  796. Q_strncpy( filename, fn, sizeof( filename ) );
  797. filename[ strlen( filename ) - 4 ] = 0;
  798. m_pAdvCrosshairStyle->AddItem( filename, "" );
  799. // check to see if this is the one we have set
  800. if ( crosshairfile[0] )
  801. {
  802. Q_snprintf( filename, sizeof(filename), "materials/vgui/crosshairs/%s", fn );
  803. if (!stricmp(filename, crosshairfile))
  804. {
  805. if ( ModInfo().AdvCrosshairLevel() == 1 )
  806. {
  807. initialItem = i+1;
  808. }
  809. else
  810. {
  811. initialItem = i;
  812. }
  813. }
  814. }
  815. ++i;
  816. }
  817. }
  818. fn = g_pFullFileSystem->FindNext( fh );
  819. }
  820. g_pFullFileSystem->FindClose( fh );
  821. m_pAdvCrosshairStyle->SetInitialItem(initialItem);
  822. }
  823. //-----------------------------------------------------------------------------
  824. // Purpose: Called whenever style combo changes
  825. //-----------------------------------------------------------------------------
  826. void CrosshairImagePanelAdvanced::OnTextChanged(vgui::Panel *panel)
  827. {
  828. m_pOptionsPanel->OnControlModified();
  829. UpdateCrosshair();
  830. }
  831. //-----------------------------------------------------------------------------
  832. // Purpose: Called whenever one of the color or scale sliders move
  833. //-----------------------------------------------------------------------------
  834. void CrosshairImagePanelAdvanced::OnSliderMoved(KeyValues *data)
  835. {
  836. m_pOptionsPanel->OnControlModified();
  837. UpdateCrosshair();
  838. }
  839. void CrosshairImagePanelAdvanced::ResetData()
  840. {
  841. m_pAdvCrosshairRedSlider->Reset();
  842. m_pAdvCrosshairGreenSlider->Reset();
  843. m_pAdvCrosshairBlueSlider->Reset();
  844. m_pAdvCrosshairScaleSlider->Reset();
  845. // TODO: update style combo from cvar
  846. }
  847. void CrosshairImagePanelAdvanced::ApplyChanges()
  848. {
  849. m_pAdvCrosshairRedSlider->ApplyChanges();
  850. m_pAdvCrosshairGreenSlider->ApplyChanges();
  851. m_pAdvCrosshairBlueSlider->ApplyChanges();
  852. m_pAdvCrosshairScaleSlider->ApplyChanges();
  853. // save the crosshair
  854. char cmd[512];
  855. char crosshair[256];
  856. m_pAdvCrosshairStyle->GetText(crosshair, sizeof(crosshair));
  857. if ( ModInfo().AdvCrosshairLevel() == 1 && m_pAdvCrosshairStyle->GetActiveItem() == 0 ) // this is the "none" selection
  858. {
  859. engine->ClientCmd_Unrestricted("cl_crosshair_file \"\"");
  860. }
  861. else
  862. {
  863. Q_snprintf(cmd, sizeof(cmd), "cl_crosshair_file %s\n", crosshair);
  864. engine->ClientCmd_Unrestricted(cmd);
  865. }
  866. }
  867. void CrosshairImagePanelAdvanced::UpdateVisibility()
  868. {
  869. SetVisible(true);
  870. m_pAdvCrosshairRedSlider->SetVisible(true);
  871. m_pAdvCrosshairBlueSlider->SetVisible(true);
  872. m_pAdvCrosshairGreenSlider->SetVisible(true);
  873. m_pAdvCrosshairScaleSlider->SetVisible(true);
  874. m_pAdvCrosshairStyle->SetVisible(true);
  875. if ( ModInfo().NoCrosshair() )
  876. {
  877. Panel *pTempPanel = NULL;
  878. pTempPanel = FindSiblingByName( "CrosshairImage" );
  879. pTempPanel->SetVisible( false );
  880. pTempPanel = FindSiblingByName( "CrosshairLabel" );
  881. if ( pTempPanel )
  882. pTempPanel->SetVisible( false );
  883. }
  884. }
  885. //-----------------------------------------------------------------------------
  886. // Purpose: Basic help dialog
  887. //-----------------------------------------------------------------------------
  888. COptionsSubMultiplayer::COptionsSubMultiplayer(vgui::Panel *parent) : vgui::PropertyPage(parent, "OptionsSubMultiplayer")
  889. {
  890. Button *cancel = new Button( this, "Cancel", "#GameUI_Cancel" );
  891. cancel->SetCommand( "Close" );
  892. Button *ok = new Button( this, "OK", "#GameUI_OK" );
  893. ok->SetCommand( "Ok" );
  894. Button *apply = new Button( this, "Apply", "#GameUI_Apply" );
  895. apply->SetCommand( "Apply" );
  896. Button *advanced = new Button( this, "Advanced", "#GameUI_AdvancedEllipsis" );
  897. advanced->SetCommand( "Advanced" );
  898. Button *importSprayImage = new Button( this, "ImportSprayImage", "#GameUI_ImportSprayEllipsis" );
  899. importSprayImage->SetCommand("ImportSprayImage");
  900. m_hImportSprayDialog = NULL;
  901. m_pPrimaryColorSlider = new CCvarSlider( this, "Primary Color Slider", "#GameUI_PrimaryColor",
  902. 0.0f, 255.0f, "topcolor" );
  903. m_pSecondaryColorSlider = new CCvarSlider( this, "Secondary Color Slider", "#GameUI_SecondaryColor",
  904. 0.0f, 255.0f, "bottomcolor" );
  905. m_pHighQualityModelCheckBox = new CCvarToggleCheckButton( this, "High Quality Models", "#GameUI_HighModels", "cl_himodels" );
  906. m_pModelList = new CLabeledCommandComboBox( this, "Player model" );
  907. m_ModelName[0] = 0;
  908. InitModelList( m_pModelList );
  909. m_pLogoList = new CLabeledCommandComboBox( this, "SpraypaintList" );
  910. m_LogoName[0] = 0;
  911. InitLogoList( m_pLogoList );
  912. m_pModelImage = new CBitmapImagePanel( this, "ModelImage", NULL );
  913. m_pModelImage->AddActionSignalTarget( this );
  914. m_pLogoImage = new ImagePanel( this, "LogoImage" );
  915. m_pLogoImage->AddActionSignalTarget( this );
  916. m_nLogoR = 255;
  917. m_nLogoG = 255;
  918. m_nLogoB = 255;
  919. m_pCrosshairImage = NULL;
  920. switch ( ModInfo().AdvCrosshairLevel() )
  921. {
  922. case 0:
  923. if ( !ModInfo().NoCrosshair() )
  924. m_pCrosshairImage = new CrosshairImagePanelSimple( this, "CrosshairImage", this );
  925. break;
  926. case 1: // TF
  927. case 2: // DOD
  928. m_pCrosshairImage = new CrosshairImagePanelAdvanced( this, "AdvCrosshairImage", this );
  929. break;
  930. case 3: // Counter-Strike
  931. m_pCrosshairImage = new CrosshairImagePanelCS( this, "CrosshairImage", this );
  932. break;
  933. }
  934. m_pLockRadarRotationCheckbox = new CCvarToggleCheckButton( this, "LockRadarRotationCheckbox", "#Cstrike_RadarLocked", "cl_radar_locked" );
  935. m_pDownloadFilterCombo = new ComboBox( this, "DownloadFilterCheck", 4, false );
  936. m_pDownloadFilterCombo->AddItem( "#GameUI_DownloadFilter_ALL", NULL );
  937. m_pDownloadFilterCombo->AddItem( "#GameUI_DownloadFilter_NoSounds", NULL );
  938. m_pDownloadFilterCombo->AddItem( "#GameUI_DownloadFilter_MapsOnly", NULL );
  939. m_pDownloadFilterCombo->AddItem( "#GameUI_DownloadFilter_None", NULL );
  940. //=========
  941. LoadControlSettings("Resource/OptionsSubMultiplayer.res");
  942. // this is necessary because some of the game .res files don't have visiblity flags set up correctly for their controls
  943. if ( m_pCrosshairImage )
  944. m_pCrosshairImage->UpdateVisibility();
  945. // turn off model selection stuff if the mod specifies "nomodels" in the gameinfo.txt file
  946. if ( ModInfo().NoModels() )
  947. {
  948. Panel *pTempPanel = NULL;
  949. if ( m_pModelImage )
  950. {
  951. m_pModelImage->SetVisible( false );
  952. }
  953. if ( m_pModelList )
  954. {
  955. m_pModelList->SetVisible( false );
  956. }
  957. if ( m_pPrimaryColorSlider )
  958. {
  959. m_pPrimaryColorSlider->SetVisible( false );
  960. }
  961. if ( m_pSecondaryColorSlider )
  962. {
  963. m_pSecondaryColorSlider->SetVisible( false );
  964. }
  965. // #GameUI_PlayerModel (from "Resource/OptionsSubMultiplayer.res")
  966. pTempPanel = FindChildByName( "Label1" );
  967. if ( pTempPanel )
  968. {
  969. pTempPanel->SetVisible( false );
  970. }
  971. // #GameUI_ColorSliders (from "Resource/OptionsSubMultiplayer.res")
  972. pTempPanel = FindChildByName( "Colors" );
  973. if ( pTempPanel )
  974. {
  975. pTempPanel->SetVisible( false );
  976. }
  977. }
  978. // turn off the himodel stuff if the mod specifies "nohimodel" in the gameinfo.txt file
  979. if ( ModInfo().NoHiModel() )
  980. {
  981. if ( m_pHighQualityModelCheckBox )
  982. {
  983. m_pHighQualityModelCheckBox->SetVisible( false );
  984. }
  985. }
  986. }
  987. //-----------------------------------------------------------------------------
  988. // Purpose:
  989. //-----------------------------------------------------------------------------
  990. COptionsSubMultiplayer::~COptionsSubMultiplayer()
  991. {
  992. }
  993. //-----------------------------------------------------------------------------
  994. // Purpose:
  995. //-----------------------------------------------------------------------------
  996. void COptionsSubMultiplayer::OnCommand( const char *command )
  997. {
  998. if ( !stricmp( command, "Advanced" ) )
  999. {
  1000. #ifndef _XBOX
  1001. if (!m_hMultiplayerAdvancedDialog.Get())
  1002. {
  1003. m_hMultiplayerAdvancedDialog = new CMultiplayerAdvancedDialog( this );
  1004. }
  1005. m_hMultiplayerAdvancedDialog->Activate();
  1006. #endif
  1007. }
  1008. else if (!stricmp( command, "ImportSprayImage" ) )
  1009. {
  1010. if (m_hImportSprayDialog == NULL)
  1011. {
  1012. m_hImportSprayDialog = new FileOpenDialog(NULL, "#GameUI_ImportSprayImage", true);
  1013. #ifdef WIN32
  1014. m_hImportSprayDialog->AddFilter("*.tga,*.jpg,*.bmp,*.vtf", "#GameUI_All_Images", true);
  1015. #else
  1016. m_hImportSprayDialog->AddFilter("*.tga,*.jpg,*.vtf", "#GameUI_All_ImagesNoBmp", true);
  1017. #endif
  1018. m_hImportSprayDialog->AddFilter("*.tga", "#GameUI_TGA_Images", false);
  1019. m_hImportSprayDialog->AddFilter("*.jpg", "#GameUI_JPEG_Images", false);
  1020. #ifdef WIN32
  1021. m_hImportSprayDialog->AddFilter("*.bmp", "#GameUI_BMP_Images", false);
  1022. #endif
  1023. m_hImportSprayDialog->AddFilter("*.vtf", "#GameUI_VTF_Images", false);
  1024. m_hImportSprayDialog->AddActionSignalTarget(this);
  1025. }
  1026. m_hImportSprayDialog->DoModal(false);
  1027. m_hImportSprayDialog->Activate();
  1028. }
  1029. else if ( !stricmp( command, "ResetStats" ) )
  1030. {
  1031. QueryBox *box = new QueryBox("#GameUI_ConfirmResetStatsTitle", "#GameUI_ConfirmResetStatsText", this);
  1032. box->SetOKButtonText("#GameUI_Reset");
  1033. box->SetOKCommand(new KeyValues("Command", "command", "ResetStats_NoConfirm"));
  1034. box->SetCancelCommand(new KeyValues("Command", "command", "ReleaseModalWindow"));
  1035. box->AddActionSignalTarget(this);
  1036. box->DoModal();
  1037. }
  1038. else if ( !stricmp( command, "ResetStats_NoConfirm" ) )
  1039. {
  1040. engine->ClientCmd_Unrestricted("stats_reset");
  1041. }
  1042. BaseClass::OnCommand( command );
  1043. }
  1044. void COptionsSubMultiplayer::ConversionError( ConversionErrorType nError )
  1045. {
  1046. const char *pErrorText = NULL;
  1047. switch ( nError )
  1048. {
  1049. case CE_MEMORY_ERROR:
  1050. pErrorText = "#GameUI_Spray_Import_Error_Memory";
  1051. break;
  1052. case CE_CANT_OPEN_SOURCE_FILE:
  1053. pErrorText = "#GameUI_Spray_Import_Error_Reading_Image";
  1054. break;
  1055. case CE_ERROR_PARSING_SOURCE:
  1056. pErrorText = "#GameUI_Spray_Import_Error_Image_File_Corrupt";
  1057. break;
  1058. case CE_SOURCE_FILE_SIZE_NOT_SUPPORTED:
  1059. pErrorText = "#GameUI_Spray_Import_Image_Wrong_Size";
  1060. break;
  1061. case CE_SOURCE_FILE_FORMAT_NOT_SUPPORTED:
  1062. pErrorText = "#GameUI_Spray_Import_Image_Wrong_Size";
  1063. break;
  1064. case CE_SOURCE_FILE_TGA_FORMAT_NOT_SUPPORTED:
  1065. pErrorText = "#GameUI_Spray_Import_Error_TGA_Format_Not_Supported";
  1066. break;
  1067. case CE_SOURCE_FILE_BMP_FORMAT_NOT_SUPPORTED:
  1068. pErrorText = "#GameUI_Spray_Import_Error_BMP_Format_Not_Supported";
  1069. break;
  1070. case CE_ERROR_WRITING_OUTPUT_FILE:
  1071. pErrorText = "#GameUI_Spray_Import_Error_Writing_Temp_Output";
  1072. break;
  1073. case CE_ERROR_LOADING_DLL:
  1074. pErrorText = "#GameUI_Spray_Import_Error_Cant_Load_VTEX_DLL";
  1075. break;
  1076. }
  1077. if ( pErrorText )
  1078. {
  1079. // Create the dialog
  1080. vgui::MessageBox *pErrorDlg = new vgui::MessageBox("#GameUI_Spray_Import_Error_Title", pErrorText ); Assert( pErrorDlg );
  1081. // Display
  1082. if ( pErrorDlg ) // Check for a NULL just to be extra cautious...
  1083. {
  1084. pErrorDlg->DoModal();
  1085. }
  1086. }
  1087. }
  1088. void COptionsSubMultiplayer::OnFileSelected(const char *fullpath)
  1089. {
  1090. #ifndef _XBOX
  1091. // this can take a while, put up a waiting cursor
  1092. surface()->SetCursor(dc_hourglass);
  1093. ConversionErrorType nErrorCode = ImgUtl_ConvertToVTFAndDumpVMT( fullpath, IsPosix() ? "/vgui/logos" : "\\vgui\\logos", 256, 256 );
  1094. if ( nErrorCode == CE_SUCCESS )
  1095. {
  1096. // refresh the logo list so the new spray shows up.
  1097. InitLogoList(m_pLogoList);
  1098. // Get the filename
  1099. char szRootFilename[MAX_PATH];
  1100. V_FileBase( fullpath, szRootFilename, sizeof( szRootFilename ) );
  1101. // automatically select the logo that was just imported.
  1102. SelectLogo(szRootFilename);
  1103. }
  1104. else
  1105. {
  1106. ConversionError( nErrorCode );
  1107. }
  1108. // change the cursor back to normal
  1109. surface()->SetCursor(dc_user);
  1110. #endif
  1111. }
  1112. struct ValveJpegErrorHandler_t
  1113. {
  1114. // The default manager
  1115. struct jpeg_error_mgr m_Base;
  1116. // For handling any errors
  1117. jmp_buf m_ErrorContext;
  1118. };
  1119. //-----------------------------------------------------------------------------
  1120. // Purpose: We'll override the default error handler so we can deal with errors without having to exit the engine
  1121. //-----------------------------------------------------------------------------
  1122. static void ValveJpegErrorHandler( j_common_ptr cinfo )
  1123. {
  1124. ValveJpegErrorHandler_t *pError = reinterpret_cast< ValveJpegErrorHandler_t * >( cinfo->err );
  1125. char buffer[ JMSG_LENGTH_MAX ];
  1126. /* Create the message */
  1127. ( *cinfo->err->format_message )( cinfo, buffer );
  1128. Warning( "%s\n", buffer );
  1129. // Bail
  1130. longjmp( pError->m_ErrorContext, 1 );
  1131. }
  1132. //-----------------------------------------------------------------------------
  1133. // Purpose: Builds the list of logos
  1134. //-----------------------------------------------------------------------------
  1135. void COptionsSubMultiplayer::InitLogoList( CLabeledCommandComboBox *cb )
  1136. {
  1137. // Find out images
  1138. FileFindHandle_t fh;
  1139. char directory[ 512 ];
  1140. ConVarRef cl_logofile( "cl_logofile", true );
  1141. if ( !cl_logofile.IsValid() )
  1142. return;
  1143. cb->DeleteAllItems();
  1144. const char *logofile = cl_logofile.GetString();
  1145. Q_snprintf( directory, sizeof( directory ), "materials/vgui/logos/*.vtf" );
  1146. const char *fn = g_pFullFileSystem->FindFirst( directory, &fh );
  1147. int i = 0, initialItem = 0;
  1148. while (fn)
  1149. {
  1150. char filename[ 512 ];
  1151. Q_snprintf( filename, sizeof(filename), "materials/vgui/logos/%s", fn );
  1152. if ( strlen( filename ) >= 4 )
  1153. {
  1154. filename[ strlen( filename ) - 4 ] = 0;
  1155. Q_strncat( filename, ".vmt", sizeof( filename ), COPY_ALL_CHARACTERS );
  1156. if ( g_pFullFileSystem->FileExists( filename ) )
  1157. {
  1158. // strip off the extension
  1159. Q_strncpy( filename, fn, sizeof( filename ) );
  1160. filename[ strlen( filename ) - 4 ] = 0;
  1161. cb->AddItem( filename, "" );
  1162. // check to see if this is the one we have set
  1163. Q_snprintf( filename, sizeof(filename), "materials/vgui/logos/%s", fn );
  1164. if (!Q_stricmp(filename, logofile))
  1165. {
  1166. initialItem = i;
  1167. }
  1168. ++i;
  1169. }
  1170. }
  1171. fn = g_pFullFileSystem->FindNext( fh );
  1172. }
  1173. g_pFullFileSystem->FindClose( fh );
  1174. cb->SetInitialItem(initialItem);
  1175. }
  1176. //-----------------------------------------------------------------------------
  1177. // Purpose: Selects the given logo in the logo list.
  1178. //-----------------------------------------------------------------------------
  1179. void COptionsSubMultiplayer::SelectLogo(const char *logoName)
  1180. {
  1181. int numEntries = m_pLogoList->GetItemCount();
  1182. int index;
  1183. wchar_t itemText[MAX_PATH];
  1184. wchar_t itemToSelectText[MAX_PATH];
  1185. // convert the logo filename to unicode
  1186. g_pVGuiLocalize->ConvertANSIToUnicode(logoName, itemToSelectText, sizeof(itemToSelectText));
  1187. // find the index of the spray we want.
  1188. for (index = 0; index < numEntries; ++index)
  1189. {
  1190. m_pLogoList->GetItemText(index, itemText, sizeof(itemText));
  1191. if (!wcscmp(itemText, itemToSelectText))
  1192. {
  1193. break;
  1194. }
  1195. }
  1196. if (index < numEntries)
  1197. {
  1198. // select the logo.
  1199. m_pLogoList->ActivateItem(index);
  1200. }
  1201. }
  1202. #define MODEL_MATERIAL_BASE_FOLDER "materials/vgui/playermodels/"
  1203. void StripStringOutOfString( const char *pPattern, const char *pIn, char *pOut )
  1204. {
  1205. int iLengthBase = strlen( pPattern );
  1206. int iLengthString = strlen( pIn );
  1207. int k = 0;
  1208. for ( int j = iLengthBase; j < iLengthString; j++ )
  1209. {
  1210. pOut[k] = pIn[j];
  1211. k++;
  1212. }
  1213. pOut[k] = 0;
  1214. }
  1215. void FindVMTFilesInFolder( const char *pFolder, const char *pFolderName, CLabeledCommandComboBox *cb, int &iCount, int &iInitialItem )
  1216. {
  1217. ConVarRef cl_modelfile( "cl_playermodel", true );
  1218. if ( !cl_modelfile.IsValid() )
  1219. return;
  1220. char directory[ 512 ];
  1221. Q_snprintf( directory, sizeof( directory ), "%s/*.*", pFolder );
  1222. FileFindHandle_t fh;
  1223. const char *fn = g_pFullFileSystem->FindFirst( directory, &fh );
  1224. const char *modelfile = cl_modelfile.GetString();
  1225. while ( fn )
  1226. {
  1227. if ( !stricmp( fn, ".") || !stricmp( fn, "..") )
  1228. {
  1229. fn = g_pFullFileSystem->FindNext( fh );
  1230. continue;
  1231. }
  1232. if ( g_pFullFileSystem->FindIsDirectory( fh ) )
  1233. {
  1234. char folderpath[512];
  1235. Q_snprintf( folderpath, sizeof( folderpath ), "%s/%s", pFolder, fn );
  1236. FindVMTFilesInFolder( folderpath, fn, cb, iCount, iInitialItem );
  1237. fn = g_pFullFileSystem->FindNext( fh );
  1238. continue;
  1239. }
  1240. if ( !strstr( fn, ".vmt" ) )
  1241. {
  1242. fn = g_pFullFileSystem->FindNext( fh );
  1243. continue;
  1244. }
  1245. char filename[ 512 ];
  1246. Q_snprintf( filename, sizeof(filename), "%s/%s", pFolder, fn );
  1247. if ( strlen( filename ) >= 4 )
  1248. {
  1249. filename[ strlen( filename ) - 4 ] = 0;
  1250. Q_strncat( filename, ".vmt", sizeof( filename ), COPY_ALL_CHARACTERS );
  1251. if ( g_pFullFileSystem->FileExists( filename ) )
  1252. {
  1253. char displayname[ 512 ];
  1254. char texturepath[ 512 ];
  1255. // strip off the extension
  1256. Q_strncpy( displayname, fn, sizeof( displayname ) );
  1257. StripStringOutOfString( MODEL_MATERIAL_BASE_FOLDER, filename, texturepath );
  1258. displayname[ strlen( displayname ) - 4 ] = 0;
  1259. if ( CORRECT_PATH_SEPARATOR == texturepath[0] )
  1260. cb->AddItem( displayname, texturepath + 1 ); // ignore the initial "/" in texture path
  1261. else
  1262. cb->AddItem( displayname, texturepath );
  1263. char realname[ 512 ];
  1264. Q_FileBase( modelfile, realname, sizeof( realname ) );
  1265. Q_FileBase( filename, filename, sizeof( filename ) );
  1266. if (!stricmp(filename, realname))
  1267. {
  1268. iInitialItem = iCount;
  1269. }
  1270. ++iCount;
  1271. }
  1272. }
  1273. fn = g_pFullFileSystem->FindNext( fh );
  1274. }
  1275. }
  1276. //-----------------------------------------------------------------------------
  1277. // Purpose: Builds model list
  1278. //-----------------------------------------------------------------------------
  1279. void COptionsSubMultiplayer::InitModelList( CLabeledCommandComboBox *cb )
  1280. {
  1281. // Find out images
  1282. int i = 0, initialItem = 0;
  1283. cb->DeleteAllItems();
  1284. FindVMTFilesInFolder( MODEL_MATERIAL_BASE_FOLDER, "", cb, i, initialItem );
  1285. cb->SetInitialItem( initialItem );
  1286. }
  1287. //-----------------------------------------------------------------------------
  1288. // Purpose:
  1289. //-----------------------------------------------------------------------------
  1290. void COptionsSubMultiplayer::RemapLogo()
  1291. {
  1292. char logoname[256];
  1293. m_pLogoList->GetText( logoname, sizeof( logoname ) );
  1294. if( !logoname[ 0 ] )
  1295. return;
  1296. char fullLogoName[512];
  1297. // make sure there is a version with the proper shader
  1298. g_pFullFileSystem->CreateDirHierarchy( "materials/VGUI/logos/UI", "GAME" );
  1299. Q_snprintf( fullLogoName, sizeof( fullLogoName ), "materials/VGUI/logos/UI/%s.vmt", logoname );
  1300. if ( !g_pFullFileSystem->FileExists( fullLogoName ) )
  1301. {
  1302. FileHandle_t fp = g_pFullFileSystem->Open( fullLogoName, "wb" );
  1303. if ( !fp )
  1304. return;
  1305. char data[1024];
  1306. Q_snprintf( data, sizeof( data ), "\"UnlitGeneric\"\n\
  1307. {\n\
  1308. // Original shader: BaseTimesVertexColorAlphaBlendNoOverbright\n\
  1309. \"$translucent\" 1\n\
  1310. \"$basetexture\" \"VGUI/logos/%s\"\n\
  1311. \"$vertexcolor\" 1\n\
  1312. \"$vertexalpha\" 1\n\
  1313. \"$no_fullbright\" 1\n\
  1314. \"$ignorez\" 1\n\
  1315. }\n\
  1316. ", logoname );
  1317. g_pFullFileSystem->Write( data, strlen( data ), fp );
  1318. g_pFullFileSystem->Close( fp );
  1319. }
  1320. Q_snprintf( fullLogoName, sizeof( fullLogoName ), "logos/UI/%s", logoname );
  1321. m_pLogoImage->SetImage( fullLogoName );
  1322. }
  1323. //-----------------------------------------------------------------------------
  1324. // Purpose:
  1325. //-----------------------------------------------------------------------------
  1326. void COptionsSubMultiplayer::RemapModel()
  1327. {
  1328. const char *pModelName = m_pModelList->GetActiveItemCommand();
  1329. if( pModelName == NULL )
  1330. return;
  1331. char texture[ 256 ];
  1332. Q_snprintf ( texture, sizeof( texture ), "vgui/playermodels/%s", pModelName );
  1333. texture[ strlen( texture ) - 4 ] = 0;
  1334. m_pModelImage->setTexture( texture );
  1335. }
  1336. //-----------------------------------------------------------------------------
  1337. // Purpose: Called whenever model name changes
  1338. //-----------------------------------------------------------------------------
  1339. void COptionsSubMultiplayer::OnTextChanged(vgui::Panel *panel)
  1340. {
  1341. RemapModel();
  1342. RemapLogo();
  1343. }
  1344. //-----------------------------------------------------------------------------
  1345. // Purpose:
  1346. //-----------------------------------------------------------------------------
  1347. void COptionsSubMultiplayer::OnControlModified()
  1348. {
  1349. PostMessage(GetParent(), new KeyValues("ApplyButtonEnable"));
  1350. InvalidateLayout();
  1351. }
  1352. #define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
  1353. #define SUIT_HUE_START 192
  1354. #define SUIT_HUE_END 223
  1355. #define PLATE_HUE_START 160
  1356. #define PLATE_HUE_END 191
  1357. #ifdef POSIX
  1358. typedef struct tagRGBQUAD {
  1359. uint8 rgbBlue;
  1360. uint8 rgbGreen;
  1361. uint8 rgbRed;
  1362. uint8 rgbReserved;
  1363. } RGBQUAD;
  1364. #endif
  1365. //-----------------------------------------------------------------------------
  1366. // Purpose:
  1367. //-----------------------------------------------------------------------------
  1368. static void PaletteHueReplace( RGBQUAD *palSrc, int newHue, int Start, int end )
  1369. {
  1370. int i;
  1371. float r, b, g;
  1372. float maxcol, mincol;
  1373. float hue, val, sat;
  1374. hue = (float)(newHue * (360.0 / 255));
  1375. for (i = Start; i <= end; i++)
  1376. {
  1377. b = palSrc[ i ].rgbBlue;
  1378. g = palSrc[ i ].rgbGreen;
  1379. r = palSrc[ i ].rgbRed;
  1380. maxcol = max( max( r, g ), b ) / 255.0f;
  1381. mincol = min( min( r, g ), b ) / 255.0f;
  1382. val = maxcol;
  1383. sat = (maxcol - mincol) / maxcol;
  1384. mincol = val * (1.0f - sat);
  1385. if (hue <= 120)
  1386. {
  1387. b = mincol;
  1388. if (hue < 60)
  1389. {
  1390. r = val;
  1391. g = mincol + hue * (val - mincol)/(120 - hue);
  1392. }
  1393. else
  1394. {
  1395. g = val;
  1396. r = mincol + (120 - hue)*(val-mincol)/hue;
  1397. }
  1398. }
  1399. else if (hue <= 240)
  1400. {
  1401. r = mincol;
  1402. if (hue < 180)
  1403. {
  1404. g = val;
  1405. b = mincol + (hue - 120)*(val-mincol)/(240 - hue);
  1406. }
  1407. else
  1408. {
  1409. b = val;
  1410. g = mincol + (240 - hue)*(val-mincol)/(hue - 120);
  1411. }
  1412. }
  1413. else
  1414. {
  1415. g = mincol;
  1416. if (hue < 300)
  1417. {
  1418. b = val;
  1419. r = mincol + (hue - 240)*(val-mincol)/(360 - hue);
  1420. }
  1421. else
  1422. {
  1423. r = val;
  1424. b = mincol + (360 - hue)*(val-mincol)/(hue - 240);
  1425. }
  1426. }
  1427. palSrc[ i ].rgbBlue = (unsigned char)(b * 255);
  1428. palSrc[ i ].rgbGreen = (unsigned char)(g * 255);
  1429. palSrc[ i ].rgbRed = (unsigned char)(r * 255);
  1430. }
  1431. }
  1432. //-----------------------------------------------------------------------------
  1433. // Purpose:
  1434. //-----------------------------------------------------------------------------
  1435. void COptionsSubMultiplayer::ColorForName( char const *pszColorName, int&r, int&g, int&b )
  1436. {
  1437. r = g = b = 0;
  1438. int count = sizeof( itemlist ) / sizeof( itemlist[0] );
  1439. for ( int i = 0; i < count; i++ )
  1440. {
  1441. if (!Q_strnicmp(pszColorName, itemlist[ i ].name, strlen(itemlist[ i ].name)))
  1442. {
  1443. r = itemlist[ i ].r;
  1444. g = itemlist[ i ].g;
  1445. b = itemlist[ i ].b;
  1446. return;
  1447. }
  1448. }
  1449. }
  1450. //-----------------------------------------------------------------------------
  1451. // Purpose:
  1452. //-----------------------------------------------------------------------------
  1453. void COptionsSubMultiplayer::OnResetData()
  1454. {
  1455. // reset the DownloadFilter combo box
  1456. if ( m_pDownloadFilterCombo )
  1457. {
  1458. // cl_downloadfilter
  1459. ConVarRef cl_downloadfilter( "cl_downloadfilter");
  1460. if ( Q_stricmp( cl_downloadfilter.GetString(), "none" ) == 0 )
  1461. {
  1462. m_pDownloadFilterCombo->ActivateItem( 3 );
  1463. }
  1464. else if ( Q_stricmp( cl_downloadfilter.GetString(), "nosounds" ) == 0 )
  1465. {
  1466. m_pDownloadFilterCombo->ActivateItem( 1 );
  1467. }
  1468. else if ( Q_stricmp( cl_downloadfilter.GetString(), "mapsonly" ) == 0 )
  1469. {
  1470. m_pDownloadFilterCombo->ActivateItem( 2 );
  1471. }
  1472. else
  1473. {
  1474. m_pDownloadFilterCombo->ActivateItem( 0 );
  1475. }
  1476. }
  1477. if ( m_pCrosshairImage )
  1478. m_pCrosshairImage->ResetData();
  1479. }
  1480. //-----------------------------------------------------------------------------
  1481. // Purpose:
  1482. //-----------------------------------------------------------------------------
  1483. void COptionsSubMultiplayer::OnApplyChanges()
  1484. {
  1485. m_pPrimaryColorSlider->ApplyChanges();
  1486. m_pSecondaryColorSlider->ApplyChanges();
  1487. // m_pModelList->ApplyChanges();
  1488. m_pLogoList->ApplyChanges();
  1489. m_pLogoList->GetText(m_LogoName, sizeof(m_LogoName));
  1490. m_pHighQualityModelCheckBox->ApplyChanges();
  1491. for ( int i=0; i<m_cvarToggleCheckButtons.GetCount(); ++i )
  1492. {
  1493. CCvarToggleCheckButton *toggleButton = m_cvarToggleCheckButtons[i];
  1494. if( toggleButton->IsVisible() && toggleButton->IsEnabled() )
  1495. {
  1496. toggleButton->ApplyChanges();
  1497. }
  1498. }
  1499. if ( m_pLockRadarRotationCheckbox != NULL )
  1500. {
  1501. m_pLockRadarRotationCheckbox->ApplyChanges();
  1502. }
  1503. if ( m_pCrosshairImage != NULL )
  1504. m_pCrosshairImage->ApplyChanges();
  1505. // save the logo name
  1506. char cmd[512];
  1507. if ( m_LogoName[ 0 ] )
  1508. {
  1509. Q_snprintf(cmd, sizeof(cmd), "cl_logofile materials/vgui/logos/%s.vtf\n", m_LogoName);
  1510. }
  1511. else
  1512. {
  1513. Q_strncpy( cmd, "cl_logofile \"\"\n", sizeof( cmd ) );
  1514. }
  1515. engine->ClientCmd_Unrestricted(cmd);
  1516. if ( m_pModelList && m_pModelList->IsVisible() && m_pModelList->GetActiveItemCommand() )
  1517. {
  1518. Q_strncpy( m_ModelName, m_pModelList->GetActiveItemCommand(), sizeof( m_ModelName ) );
  1519. Q_StripExtension( m_ModelName, m_ModelName, sizeof ( m_ModelName ) );
  1520. // save the player model name
  1521. Q_snprintf(cmd, sizeof(cmd), "cl_playermodel models/%s.mdl\n", m_ModelName );
  1522. engine->ClientCmd_Unrestricted(cmd);
  1523. }
  1524. else
  1525. {
  1526. m_ModelName[0] = 0;
  1527. }
  1528. // set the DownloadFilter cvar
  1529. if ( m_pDownloadFilterCombo )
  1530. {
  1531. ConVarRef cl_downloadfilter( "cl_downloadfilter" );
  1532. switch ( m_pDownloadFilterCombo->GetActiveItem() )
  1533. {
  1534. default:
  1535. case 0:
  1536. cl_downloadfilter.SetValue( "all" );
  1537. break;
  1538. case 1:
  1539. cl_downloadfilter.SetValue( "nosounds" );
  1540. break;
  1541. case 2:
  1542. cl_downloadfilter.SetValue( "mapsonly" );
  1543. break;
  1544. case 3:
  1545. cl_downloadfilter.SetValue( "none" );
  1546. break;
  1547. }
  1548. }
  1549. }
  1550. //-----------------------------------------------------------------------------
  1551. // Purpose: Allow the res file to create controls on per-mod basis
  1552. //-----------------------------------------------------------------------------
  1553. Panel *COptionsSubMultiplayer::CreateControlByName( const char *controlName )
  1554. {
  1555. if( !Q_stricmp( "CCvarToggleCheckButton", controlName ) )
  1556. {
  1557. CCvarToggleCheckButton *newButton = new CCvarToggleCheckButton( this, controlName, "", "" );
  1558. m_cvarToggleCheckButtons.AddElement( newButton );
  1559. return newButton;
  1560. }
  1561. else
  1562. {
  1563. return BaseClass::CreateControlByName( controlName );
  1564. }
  1565. }