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.

704 lines
20 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. //
  9. // Half-Life Model Viewer (c) 1999 by Mete Ciragan
  10. //
  11. // file: ViewerSettings.cpp
  12. // last modified: May 29 1999, Mete Ciragan
  13. // copyright: The programs and associated files contained in this
  14. // distribution were developed by Mete Ciragan. The programs
  15. // are not in the public domain, but they are freely
  16. // distributable without licensing fees. These programs are
  17. // provided without guarantee or warrantee expressed or
  18. // implied.
  19. //
  20. // version: 1.2
  21. //
  22. // email: [email protected]
  23. // web: http://www.swissquake.ch/chumbalum-soft/
  24. //
  25. #include "ViewerSettings.h"
  26. #include "studiomodel.h"
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include "windows.h"
  31. ViewerSettings g_viewerSettings;
  32. ViewerSettings::ViewerSettings()
  33. {
  34. Q_memset( this, 0, sizeof( *this ) );
  35. }
  36. void InitViewerSettings ( const char *subkey )
  37. {
  38. ViewerSettings save = g_viewerSettings;
  39. memset (&g_viewerSettings, 0, sizeof (ViewerSettings));
  40. // Some values should survive. This is a crappy way to do settings in general. Sigh.
  41. {
  42. g_viewerSettings.faceposerToolsDriveMouth = save.faceposerToolsDriveMouth;
  43. }
  44. strcpy( g_viewerSettings.registrysubkey, subkey );
  45. g_pStudioModel->m_angles.Init( -90.0f, 0.0f, 0.0f );
  46. g_pStudioModel->m_origin.Init( 0.0f, 0.0f, 50.0f );
  47. g_viewerSettings.renderMode = RM_TEXTURED;
  48. g_viewerSettings.fov = 65.0f;
  49. g_viewerSettings.enableNormalMapping = true;
  50. g_viewerSettings.enableParallaxMapping = false;
  51. g_viewerSettings.showNormals = false;
  52. g_viewerSettings.showTangentFrame = false;
  53. g_viewerSettings.overlayWireframe = false;
  54. g_viewerSettings.enableSpecular = true;
  55. g_viewerSettings.playSounds = true;
  56. g_viewerSettings.bgColor[0] = 0.25f;
  57. g_viewerSettings.bgColor[1] = 0.25f;
  58. g_viewerSettings.bgColor[2] = 0.25f;
  59. g_viewerSettings.gColor[0] = 0.85f;
  60. g_viewerSettings.gColor[1] = 0.85f;
  61. g_viewerSettings.gColor[2] = 0.69f;
  62. g_viewerSettings.lColor[0] = 1.0f;
  63. g_viewerSettings.lColor[1] = 1.0f;
  64. g_viewerSettings.lColor[2] = 1.0f;
  65. g_viewerSettings.aColor[0] = 0.3f;
  66. g_viewerSettings.aColor[1] = 0.3f;
  67. g_viewerSettings.aColor[2] = 0.3f;
  68. g_viewerSettings.lightrot[0] = 0.0f;
  69. g_viewerSettings.lightrot[1] = 180.0f;
  70. g_viewerSettings.lightrot[2] = 0.0f;
  71. g_viewerSettings.speedScale = 1.0f;
  72. g_viewerSettings.application_mode = 0;
  73. g_viewerSettings.thumbnailsize = 128;
  74. g_viewerSettings.thumbnailsizeanim = 128;
  75. g_viewerSettings.m_iEditAttachment = -1;
  76. g_viewerSettings.highlightHitbox = -1;
  77. g_viewerSettings.highlightBone = -1;
  78. g_viewerSettings.speechapiindex = 0;
  79. g_viewerSettings.cclanguageid = 0;
  80. // default hlmv settings
  81. g_viewerSettings.xpos = 20;
  82. g_viewerSettings.ypos = 20;
  83. g_viewerSettings.width = 640;
  84. g_viewerSettings.height = 700;
  85. g_viewerSettings.originAxisLength = 10.0f;
  86. }
  87. bool RegReadVector( HKEY hKey, const char *szSubKey, Vector& value )
  88. {
  89. LONG lResult; // Registry function result code
  90. char szBuff[128]; // Temp. buffer
  91. DWORD dwType; // Type of key
  92. DWORD dwSize; // Size of element data
  93. dwSize = sizeof( szBuff );
  94. lResult = RegQueryValueEx(
  95. hKey, // handle to key
  96. szSubKey, // value name
  97. 0, // reserved
  98. &dwType, // type buffer
  99. (LPBYTE)szBuff, // data buffer
  100. &dwSize ); // size of data buffer
  101. if (lResult != ERROR_SUCCESS) // Failure
  102. return false;
  103. if (sscanf( szBuff, "(%f %f %f)", &value[0], &value[1], &value[2] ) != 3)
  104. return false;
  105. return true;
  106. }
  107. bool RegReadQAngle( HKEY hKey, const char *szSubKey, QAngle& value )
  108. {
  109. Vector tmp;
  110. if (RegReadVector( hKey, szSubKey, tmp ))
  111. {
  112. value.Init( tmp.x, tmp.y, tmp.z );
  113. return true;
  114. }
  115. return false;
  116. }
  117. bool RegReadColor( HKEY hKey, const char *szSubKey, float value[4] )
  118. {
  119. LONG lResult; // Registry function result code
  120. char szBuff[128]; // Temp. buffer
  121. DWORD dwType; // Type of key
  122. DWORD dwSize; // Size of element data
  123. dwSize = sizeof( szBuff );
  124. lResult = RegQueryValueEx(
  125. hKey, // handle to key
  126. szSubKey, // value name
  127. 0, // reserved
  128. &dwType, // type buffer
  129. (LPBYTE)szBuff, // data buffer
  130. &dwSize ); // size of data buffer
  131. if (lResult != ERROR_SUCCESS) // Failure
  132. return false;
  133. if (sscanf( szBuff, "(%f %f %f %f)", &value[0], &value[1], &value[2], &value[3] ) != 4)
  134. return false;
  135. return true;
  136. }
  137. bool RegWriteVector( HKEY hKey, const char *szSubKey, Vector& value )
  138. {
  139. LONG lResult; // Registry function result code
  140. char szBuff[128]; // Temp. buffer
  141. DWORD dwSize; // Size of element data
  142. sprintf( szBuff, "(%f %f %f)", value[0], value[1], value[2] );
  143. dwSize = strlen( szBuff );
  144. lResult = RegSetValueEx(
  145. hKey, // handle to key
  146. szSubKey, // value name
  147. 0, // reserved
  148. REG_SZ, // type buffer
  149. (LPBYTE)szBuff, // data buffer
  150. dwSize ); // size of data buffer
  151. if (lResult != ERROR_SUCCESS) // Failure
  152. return false;
  153. return true;
  154. }
  155. bool RegWriteQAngle( HKEY hKey, const char *szSubKey, QAngle& value )
  156. {
  157. Vector tmp;
  158. tmp.Init( value.x, value.y, value.z );
  159. return RegWriteVector( hKey, szSubKey, tmp );
  160. }
  161. bool RegWriteColor( HKEY hKey, const char *szSubKey, float value[4] )
  162. {
  163. LONG lResult; // Registry function result code
  164. char szBuff[128]; // Temp. buffer
  165. DWORD dwSize; // Size of element data
  166. sprintf( szBuff, "(%f %f %f %f)", value[0], value[1], value[2], value[3] );
  167. dwSize = strlen( szBuff );
  168. lResult = RegSetValueEx(
  169. hKey, // handle to key
  170. szSubKey, // value name
  171. 0, // reserved
  172. REG_SZ, // type buffer
  173. (LPBYTE)szBuff, // data buffer
  174. dwSize ); // size of data buffer
  175. if (lResult != ERROR_SUCCESS) // Failure
  176. return false;
  177. return true;
  178. }
  179. bool RegReadBool( HKEY hKey, const char *szSubKey, bool *value )
  180. {
  181. LONG lResult; // Registry function result code
  182. DWORD dwType; // Type of key
  183. DWORD dwSize; // Size of element data
  184. DWORD dwTemp;
  185. dwSize = sizeof( dwTemp );
  186. lResult = RegQueryValueEx(
  187. hKey, // handle to key
  188. szSubKey, // value name
  189. 0, // reserved
  190. &dwType, // type buffer
  191. (LPBYTE)&dwTemp, // data buffer
  192. &dwSize ); // size of data buffer
  193. if (lResult != ERROR_SUCCESS) // Failure
  194. return false;
  195. if (dwType != REG_DWORD)
  196. return false;
  197. *value = (dwTemp != 0);
  198. return true;
  199. }
  200. bool RegReadInt( HKEY hKey, const char *szSubKey, int *value )
  201. {
  202. LONG lResult; // Registry function result code
  203. DWORD dwType; // Type of key
  204. DWORD dwSize; // Size of element data
  205. dwSize = sizeof( DWORD );
  206. lResult = RegQueryValueEx(
  207. hKey, // handle to key
  208. szSubKey, // value name
  209. 0, // reserved
  210. &dwType, // type buffer
  211. (LPBYTE)value, // data buffer
  212. &dwSize ); // size of data buffer
  213. if (lResult != ERROR_SUCCESS) // Failure
  214. return false;
  215. if (dwType != REG_DWORD)
  216. return false;
  217. return true;
  218. }
  219. bool RegWriteInt( HKEY hKey, const char *szSubKey, int value )
  220. {
  221. LONG lResult; // Registry function result code
  222. DWORD dwSize; // Size of element data
  223. dwSize = sizeof( DWORD );
  224. lResult = RegSetValueEx(
  225. hKey, // handle to key
  226. szSubKey, // value name
  227. 0, // reserved
  228. REG_DWORD, // type buffer
  229. (LPBYTE)&value, // data buffer
  230. dwSize ); // size of data buffer
  231. if (lResult != ERROR_SUCCESS) // Failure
  232. return false;
  233. return true;
  234. }
  235. bool RegReadFloat( HKEY hKey, const char *szSubKey, float *value )
  236. {
  237. LONG lResult; // Registry function result code
  238. char szBuff[128]; // Temp. buffer
  239. DWORD dwType; // Type of key
  240. DWORD dwSize; // Size of element data
  241. dwSize = sizeof( szBuff );
  242. lResult = RegQueryValueEx(
  243. hKey, // handle to key
  244. szSubKey, // value name
  245. 0, // reserved
  246. &dwType, // type buffer
  247. (LPBYTE)szBuff, // data buffer
  248. &dwSize ); // size of data buffer
  249. if (lResult != ERROR_SUCCESS) // Failure
  250. return false;
  251. *value = atof( szBuff );
  252. return true;
  253. }
  254. bool RegWriteFloat( HKEY hKey, const char *szSubKey, float value )
  255. {
  256. LONG lResult; // Registry function result code
  257. char szBuff[128]; // Temp. buffer
  258. DWORD dwSize; // Size of element data
  259. sprintf( szBuff, "%f", value );
  260. dwSize = strlen( szBuff );
  261. lResult = RegSetValueEx(
  262. hKey, // handle to key
  263. szSubKey, // value name
  264. 0, // reserved
  265. REG_SZ, // type buffer
  266. (LPBYTE)szBuff, // data buffer
  267. dwSize ); // size of data buffer
  268. if (lResult != ERROR_SUCCESS) // Failure
  269. return false;
  270. return true;
  271. }
  272. bool RegReadString( HKEY hKey, const char *szSubKey, char *string, int size )
  273. {
  274. LONG lResult; // Registry function result code
  275. DWORD dwType; // Type of key
  276. DWORD dwSize; // Size of element data
  277. dwSize = size;
  278. lResult = RegQueryValueEx(
  279. hKey, // handle to key
  280. szSubKey, // value name
  281. 0, // reserved
  282. &dwType, // type buffer
  283. (LPBYTE)string, // data buffer
  284. &dwSize ); // size of data buffer
  285. if (lResult != ERROR_SUCCESS) // Failure
  286. return false;
  287. if (dwType != REG_SZ)
  288. return false;
  289. return true;
  290. }
  291. bool RegWriteString( HKEY hKey, const char *szSubKey, char *string )
  292. {
  293. LONG lResult; // Registry function result code
  294. DWORD dwSize; // Size of element data
  295. dwSize = strlen( string );
  296. lResult = RegSetValueEx(
  297. hKey, // handle to key
  298. szSubKey, // value name
  299. 0, // reserved
  300. REG_SZ, // type buffer
  301. (LPBYTE)string, // data buffer
  302. dwSize ); // size of data buffer
  303. if (lResult != ERROR_SUCCESS) // Failure
  304. return false;
  305. return true;
  306. }
  307. LONG RegViewerSettingsKey( const char *filename, PHKEY phKey, LPDWORD lpdwDisposition )
  308. {
  309. if (strlen( filename ) == 0)
  310. return ERROR_KEY_DELETED;
  311. char szFileName[1024];
  312. strcpy( szFileName, filename );
  313. // strip out bogus characters
  314. for (char *cp = szFileName; *cp; cp++)
  315. {
  316. if (*cp == '\\' || *cp == '/' || *cp == ':')
  317. *cp = '.';
  318. }
  319. char szModelKey[1024];
  320. sprintf( szModelKey, "Software\\Valve\\%s\\%s", g_viewerSettings.registrysubkey, szFileName );
  321. return RegCreateKeyEx(
  322. HKEY_CURRENT_USER, // handle of open key
  323. szModelKey, // address of name of subkey to open
  324. 0, // DWORD ulOptions, // reserved
  325. NULL, // Type of value
  326. REG_OPTION_NON_VOLATILE, // Store permanently in reg.
  327. KEY_ALL_ACCESS, // REGSAM samDesired, // security access mask
  328. NULL,
  329. phKey, // Key we are creating
  330. lpdwDisposition); // Type of creation
  331. }
  332. LONG RegViewerRootKey( PHKEY phKey, LPDWORD lpdwDisposition )
  333. {
  334. char szRootKey[1024];
  335. sprintf( szRootKey, "Software\\Valve\\%s", g_viewerSettings.registrysubkey );
  336. return RegCreateKeyEx(
  337. HKEY_CURRENT_USER, // handle of open key
  338. szRootKey, // address of name of subkey to open
  339. 0, // DWORD ulOptions, // reserved
  340. NULL, // Type of value
  341. REG_OPTION_NON_VOLATILE, // Store permanently in reg.
  342. KEY_ALL_ACCESS, // REGSAM samDesired, // security access mask
  343. NULL,
  344. phKey, // Key we are creating
  345. lpdwDisposition); // Type of creation
  346. }
  347. bool LoadViewerSettingsInt( char const *keyname, int *value )
  348. {
  349. LONG lResult; // Registry function result code
  350. DWORD dwDisposition; // Type of key opening event
  351. HKEY hModelKey;
  352. lResult = RegViewerSettingsKey( "hlfaceposer", &hModelKey, &dwDisposition);
  353. if (lResult != ERROR_SUCCESS) // Failure
  354. return false;
  355. // First time, just set to Valve default
  356. if (dwDisposition == REG_CREATED_NEW_KEY)
  357. {
  358. return false;
  359. }
  360. *value = 0;
  361. RegReadInt( hModelKey, keyname, value );
  362. return true;
  363. }
  364. bool SaveViewerSettingsInt ( const char *keyname, int value )
  365. {
  366. LONG lResult; // Registry function result code
  367. DWORD dwDisposition; // Type of key opening event
  368. HKEY hModelKey;
  369. lResult = RegViewerSettingsKey( "hlfaceposer", &hModelKey, &dwDisposition);
  370. if (lResult != ERROR_SUCCESS) // Failure
  371. return false;
  372. RegWriteInt( hModelKey, keyname, value );
  373. return true;
  374. }
  375. bool LoadViewerSettings (const char *filename, StudioModel *pModel )
  376. {
  377. LONG lResult; // Registry function result code
  378. DWORD dwDisposition; // Type of key opening event
  379. HKEY hModelKey;
  380. if (filename == NULL || pModel == NULL)
  381. return false;
  382. lResult = RegViewerSettingsKey( filename, &hModelKey, &dwDisposition);
  383. if (lResult != ERROR_SUCCESS) // Failure
  384. return false;
  385. // First time, just set to Valve default
  386. if (dwDisposition == REG_CREATED_NEW_KEY)
  387. {
  388. return false;
  389. }
  390. RegReadQAngle( hModelKey, "Rot", pModel->m_angles );
  391. RegReadVector( hModelKey, "Trans", pModel->m_origin );
  392. RegReadColor( hModelKey, "bgColor", g_viewerSettings.bgColor );
  393. RegReadColor( hModelKey, "gColor", g_viewerSettings.gColor );
  394. RegReadColor( hModelKey, "lColor", g_viewerSettings.lColor );
  395. RegReadColor( hModelKey, "aColor", g_viewerSettings.aColor );
  396. RegReadQAngle( hModelKey, "lightrot", g_viewerSettings.lightrot );
  397. int iTemp;
  398. float flTemp;
  399. char szTemp[256];
  400. RegReadString( hModelKey, "sequence", szTemp, sizeof( szTemp ) );
  401. iTemp = pModel->LookupSequence( szTemp );
  402. pModel->SetSequence( iTemp );
  403. RegReadString( hModelKey, "overlaySequence0", szTemp, sizeof( szTemp ) );
  404. iTemp = pModel->LookupSequence( szTemp );
  405. RegReadFloat( hModelKey, "overlayWeight0", &flTemp );
  406. pModel->SetOverlaySequence( 0, iTemp, flTemp );
  407. RegReadString( hModelKey, "overlaySequence1", szTemp, sizeof( szTemp ) );
  408. iTemp = pModel->LookupSequence( szTemp );
  409. RegReadFloat( hModelKey, "overlayWeight1", &flTemp );
  410. pModel->SetOverlaySequence( 1, iTemp, flTemp );
  411. RegReadString( hModelKey, "overlaySequence2", szTemp, sizeof( szTemp ) );
  412. iTemp = pModel->LookupSequence( szTemp );
  413. RegReadFloat( hModelKey, "overlayWeight2", &flTemp );
  414. pModel->SetOverlaySequence( 2, iTemp, flTemp );
  415. RegReadString( hModelKey, "overlaySequence3", szTemp, sizeof( szTemp ) );
  416. iTemp = pModel->LookupSequence( szTemp );
  417. RegReadFloat( hModelKey, "overlayWeight3",&flTemp );
  418. pModel->SetOverlaySequence( 3, iTemp, flTemp );
  419. RegReadFloat( hModelKey, "speedscale", &g_viewerSettings.speedScale );
  420. if (g_viewerSettings.speedScale > 1.0)
  421. g_viewerSettings.speedScale = 1.0;
  422. RegReadInt( hModelKey, "viewermode", &g_viewerSettings.application_mode );
  423. RegReadInt( hModelKey, "thumbnailsize", &g_viewerSettings.thumbnailsize );
  424. RegReadInt( hModelKey, "thumbnailsizeanim", &g_viewerSettings.thumbnailsizeanim );
  425. if ( g_viewerSettings.thumbnailsize == 0 )
  426. {
  427. g_viewerSettings.thumbnailsize = 128;
  428. }
  429. if ( g_viewerSettings.thumbnailsizeanim == 0 )
  430. {
  431. g_viewerSettings.thumbnailsizeanim = 128;
  432. }
  433. RegReadInt( hModelKey, "speechapiindex", &g_viewerSettings.speechapiindex );
  434. RegReadInt( hModelKey, "cclanguageid", &g_viewerSettings.cclanguageid );
  435. RegReadBool( hModelKey, "showground", &g_viewerSettings.showGround );
  436. RegReadBool( hModelKey, "showbackground", &g_viewerSettings.showBackground );
  437. RegReadBool( hModelKey, "showshadow", &g_viewerSettings.showShadow );
  438. RegReadBool( hModelKey, "showillumpos", &g_viewerSettings.showIllumPosition );
  439. RegReadBool( hModelKey, "enablenormalmapping", &g_viewerSettings.enableNormalMapping );
  440. RegReadBool( hModelKey, "playsounds", &g_viewerSettings.playSounds );
  441. RegReadBool( hModelKey, "showoriginaxis", &g_viewerSettings.showOriginAxis );
  442. RegReadFloat( hModelKey, "originaxislength", &g_viewerSettings.originAxisLength );
  443. char merge_buffer[32];
  444. for ( int i = 0; i < HLMV_MAX_MERGED_MODELS; i++ )
  445. {
  446. Q_snprintf( merge_buffer, sizeof( merge_buffer ), "merge%d", i + 1 );
  447. RegReadString( hModelKey, merge_buffer, g_viewerSettings.mergeModelFile[i], sizeof( g_viewerSettings.mergeModelFile[i] ) );
  448. }
  449. return true;
  450. }
  451. bool LoadViewerRootSettings( void )
  452. {
  453. LONG lResult; // Registry function result code
  454. DWORD dwDisposition; // Type of key opening event
  455. HKEY hRootKey;
  456. lResult = RegViewerRootKey( &hRootKey, &dwDisposition);
  457. if (lResult != ERROR_SUCCESS) // Failure
  458. return false;
  459. RegReadInt( hRootKey, "renderxpos", &g_viewerSettings.xpos );
  460. RegReadInt( hRootKey, "renderypos", &g_viewerSettings.ypos );
  461. RegReadInt( hRootKey, "renderwidth", &g_viewerSettings.width );
  462. RegReadInt( hRootKey, "renderheight", &g_viewerSettings.height );
  463. RegReadBool( hRootKey, "faceposerToolsDriveMouth", &g_viewerSettings.faceposerToolsDriveMouth );
  464. return true;
  465. }
  466. bool SaveViewerSettings (const char *filename, StudioModel *pModel )
  467. {
  468. LONG lResult; // Registry function result code
  469. DWORD dwDisposition; // Type of key opening event
  470. if (filename == NULL || pModel == NULL)
  471. return false;
  472. HKEY hModelKey;
  473. lResult = RegViewerSettingsKey( filename, &hModelKey, &dwDisposition);
  474. if (lResult != ERROR_SUCCESS) // Failure
  475. return false;
  476. MDLCACHE_CRITICAL_SECTION_( g_pMDLCache );
  477. CStudioHdr *hdr = pModel->GetStudioHdr();
  478. if ( !hdr )
  479. return false;
  480. RegWriteQAngle( hModelKey, "Rot", pModel->m_angles );
  481. RegWriteVector( hModelKey, "Trans", pModel->m_origin );
  482. RegWriteColor( hModelKey, "bgColor", g_viewerSettings.bgColor );
  483. RegWriteColor( hModelKey, "gColor", g_viewerSettings.gColor );
  484. RegWriteColor( hModelKey, "lColor", g_viewerSettings.lColor );
  485. RegWriteColor( hModelKey, "aColor", g_viewerSettings.aColor );
  486. RegWriteQAngle( hModelKey, "lightrot", g_viewerSettings.lightrot );
  487. RegWriteString( hModelKey, "sequence", hdr->pSeqdesc( pModel->GetSequence() ).pszLabel() );
  488. RegWriteString( hModelKey, "overlaySequence0", hdr->pSeqdesc( pModel->GetOverlaySequence( 0 ) ).pszLabel() );
  489. RegWriteFloat( hModelKey, "overlayWeight0", pModel->GetOverlaySequenceWeight( 0 ) );
  490. RegWriteString( hModelKey, "overlaySequence1", hdr->pSeqdesc( pModel->GetOverlaySequence( 1 ) ).pszLabel() );
  491. RegWriteFloat( hModelKey, "overlayWeight1", pModel->GetOverlaySequenceWeight( 1 ) );
  492. RegWriteString( hModelKey, "overlaySequence2", hdr->pSeqdesc( pModel->GetOverlaySequence( 2 ) ).pszLabel() );
  493. RegWriteFloat( hModelKey, "overlayWeight2", pModel->GetOverlaySequenceWeight( 2 ) );
  494. RegWriteString( hModelKey, "overlaySequence3", hdr->pSeqdesc( pModel->GetOverlaySequence( 3 ) ).pszLabel() );
  495. RegWriteFloat( hModelKey, "overlayWeight3", pModel->GetOverlaySequenceWeight( 3 ) );
  496. RegWriteFloat( hModelKey, "speedscale", g_viewerSettings.speedScale );
  497. RegWriteInt( hModelKey, "viewermode", g_viewerSettings.application_mode );
  498. RegWriteInt( hModelKey, "thumbnailsize", g_viewerSettings.thumbnailsize );
  499. RegWriteInt( hModelKey, "thumbnailsizeanim", g_viewerSettings.thumbnailsizeanim );
  500. RegWriteInt( hModelKey, "speechapiindex", g_viewerSettings.speechapiindex );
  501. RegWriteInt( hModelKey, "cclanguageid", g_viewerSettings.cclanguageid );
  502. RegWriteInt( hModelKey, "showground", g_viewerSettings.showGround );
  503. RegWriteInt( hModelKey, "showbackground", g_viewerSettings.showBackground );
  504. RegWriteInt( hModelKey, "showshadow", g_viewerSettings.showShadow );
  505. RegWriteInt( hModelKey, "showillumpos", g_viewerSettings.showIllumPosition );
  506. RegWriteInt( hModelKey, "enablenormalmapping", g_viewerSettings.enableNormalMapping );
  507. RegWriteInt( hModelKey, "playsounds", g_viewerSettings.playSounds );
  508. RegWriteInt( hModelKey, "showoriginaxis", g_viewerSettings.showOriginAxis );
  509. RegWriteFloat( hModelKey, "originaxislength", g_viewerSettings.originAxisLength );
  510. char merge_buffer[32];
  511. for ( int i = 0; i < HLMV_MAX_MERGED_MODELS; i++ )
  512. {
  513. Q_snprintf( merge_buffer, sizeof( merge_buffer ), "merge%d", i + 1 );
  514. RegWriteString( hModelKey, merge_buffer, g_viewerSettings.mergeModelFile[i] );
  515. }
  516. return true;
  517. }
  518. bool SaveViewerRootSettings( void )
  519. {
  520. LONG lResult; // Registry function result code
  521. DWORD dwDisposition; // Type of key opening event
  522. HKEY hRootKey;
  523. lResult = RegViewerRootKey( &hRootKey, &dwDisposition);
  524. if (lResult != ERROR_SUCCESS) // Failure
  525. return false;
  526. RegWriteInt( hRootKey, "renderxpos", g_viewerSettings.xpos );
  527. RegWriteInt( hRootKey, "renderypos", g_viewerSettings.ypos );
  528. RegWriteInt( hRootKey, "renderwidth", g_viewerSettings.width );
  529. RegWriteInt( hRootKey, "renderheight", g_viewerSettings.height );
  530. RegWriteInt( hRootKey, "faceposerToolsDriveMouth", g_viewerSettings.faceposerToolsDriveMouth ? 1 : 0 );
  531. return true;
  532. }