Counter Strike : Global Offensive Source Code
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.

472 lines
12 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "hlfaceposer.h"
  8. #include <mxtk/mx.h>
  9. #include "expressions.h"
  10. #include "StudioModel.h"
  11. #include "filesystem.h"
  12. #include "viewersettings.h"
  13. #include "matsyswin.h"
  14. #include "checksum_crc.h"
  15. #include "expclass.h"
  16. #include "ControlPanel.h"
  17. #include "faceposer_models.h"
  18. #include "mdlviewer.h"
  19. static int g_counter = 0;
  20. //-----------------------------------------------------------------------------
  21. // Purpose:
  22. //-----------------------------------------------------------------------------
  23. CExpression::CExpression( void )
  24. {
  25. name[ 0 ] = 0;
  26. index = 0;
  27. description[ 0 ] = 0;
  28. memset( setting, 0, sizeof( setting ) );
  29. for ( int i = 0; i < MAX_FP_MODELS; i++ )
  30. {
  31. m_Bitmap[ i ].valid = false;
  32. }
  33. m_nUndoCurrent = 0;
  34. m_bModified = false;
  35. m_bSelected = false;
  36. m_bDirty = false;
  37. expressionclass[ 0 ] = 0;
  38. }
  39. //-----------------------------------------------------------------------------
  40. // Purpose: Copy constructor
  41. // Input : from -
  42. //-----------------------------------------------------------------------------
  43. CExpression::CExpression( const CExpression& from )
  44. {
  45. int i;
  46. strcpy( name, from.name );
  47. index = from.index;
  48. strcpy( description, from.description );
  49. for ( i = 0; i < MAX_FP_MODELS; i++ )
  50. {
  51. m_Bitmap[ i ] = from.m_Bitmap[ i ];
  52. }
  53. m_bModified = from.m_bModified;
  54. for ( i = 0 ; i < from.undo.Count(); i++ )
  55. {
  56. CExpUndoInfo *newUndo = new CExpUndoInfo();
  57. *newUndo = *from.undo[ i ];
  58. undo.AddToTail( newUndo );
  59. }
  60. m_nUndoCurrent = from.m_nUndoCurrent;
  61. m_bSelected = from.m_bSelected;
  62. m_bDirty = from.m_bDirty;
  63. strcpy( expressionclass, from.expressionclass );
  64. memcpy( setting, from.setting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  65. memcpy( weight, from.weight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  66. }
  67. //-----------------------------------------------------------------------------
  68. // Purpose:
  69. //-----------------------------------------------------------------------------
  70. CExpression::~CExpression( void )
  71. {
  72. ResetUndo();
  73. }
  74. //-----------------------------------------------------------------------------
  75. // Purpose:
  76. // Output : Returns true on success, false on failure.
  77. //-----------------------------------------------------------------------------
  78. bool CExpression::GetDirty( void )
  79. {
  80. return m_bDirty;
  81. }
  82. //-----------------------------------------------------------------------------
  83. // Purpose:
  84. // Input : dirty -
  85. //-----------------------------------------------------------------------------
  86. void CExpression::SetDirty( bool dirty )
  87. {
  88. m_bDirty = dirty;
  89. }
  90. //-----------------------------------------------------------------------------
  91. // Purpose:
  92. // Output : float
  93. //-----------------------------------------------------------------------------
  94. float *CExpression::GetSettings( void )
  95. {
  96. return setting;
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Purpose:
  100. // Output : float
  101. //-----------------------------------------------------------------------------
  102. float *CExpression::GetWeights( void )
  103. {
  104. return weight;
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose:
  108. // Input : mod -
  109. //-----------------------------------------------------------------------------
  110. void CExpression::SetModified( bool mod )
  111. {
  112. m_bModified = mod;
  113. }
  114. //-----------------------------------------------------------------------------
  115. // Purpose:
  116. // Output : Returns true on success, false on failure.
  117. //-----------------------------------------------------------------------------
  118. bool CExpression::GetModified( void )
  119. {
  120. return m_bModified;
  121. }
  122. //-----------------------------------------------------------------------------
  123. // Purpose:
  124. // Input : selected -
  125. //-----------------------------------------------------------------------------
  126. void CExpression::SetSelected( bool selected )
  127. {
  128. m_bSelected = selected;
  129. }
  130. //-----------------------------------------------------------------------------
  131. // Purpose:
  132. // Output : Returns true on success, false on failure.
  133. //-----------------------------------------------------------------------------
  134. bool CExpression::GetSelected( void )
  135. {
  136. return m_bSelected;
  137. }
  138. //-----------------------------------------------------------------------------
  139. // Purpose:
  140. //-----------------------------------------------------------------------------
  141. void CExpression::ResetUndo( void )
  142. {
  143. CExpUndoInfo *u;
  144. for ( int i = 0; i < undo.Count(); i++ )
  145. {
  146. u = undo[ i ];
  147. delete u;
  148. }
  149. undo.RemoveAll();
  150. m_nUndoCurrent = 0;
  151. }
  152. //-----------------------------------------------------------------------------
  153. // Purpose:
  154. // Output : Returns true on success, false on failure.
  155. //-----------------------------------------------------------------------------
  156. bool CExpression::CanRedo( void )
  157. {
  158. if ( !undo.Count() )
  159. return false;
  160. if ( m_nUndoCurrent == 0 )
  161. return false;
  162. return true;
  163. }
  164. //-----------------------------------------------------------------------------
  165. // Purpose:
  166. // Output : Returns true on success, false on failure.
  167. //-----------------------------------------------------------------------------
  168. bool CExpression::CanUndo( void )
  169. {
  170. if ( !undo.Count() )
  171. return false;
  172. if ( m_nUndoCurrent >= undo.Count() )
  173. return false;
  174. return true;
  175. }
  176. //-----------------------------------------------------------------------------
  177. // Purpose:
  178. //-----------------------------------------------------------------------------
  179. int CExpression::UndoLevels( void )
  180. {
  181. return undo.Count();
  182. }
  183. //-----------------------------------------------------------------------------
  184. // Purpose:
  185. // Output : int
  186. //-----------------------------------------------------------------------------
  187. int CExpression::UndoCurrent( void )
  188. {
  189. return m_nUndoCurrent;
  190. }
  191. void ChecksumFlexControllers( bool bSpew, char const *name, CRC32_t &crc, const float *settings, const float *weights );
  192. CRC32_t CExpression::GetBitmapCRC()
  193. {
  194. CRC32_t crc;
  195. float *s = setting;
  196. float *w = weight;
  197. // Note, we'll use the pristine values if this has changed
  198. if ( undo.Count() >= 1 )
  199. {
  200. s = undo[ undo.Count() - 1 ]->setting;
  201. w = undo[ undo.Count() - 1 ]->weight;
  202. }
  203. // This walks the global controllers sorted by name and only includes values with a setting or value which is != 0.0f
  204. ChecksumFlexControllers( false, name, crc, s, w );
  205. return crc;
  206. }
  207. //-----------------------------------------------------------------------------
  208. // Purpose:
  209. // Output : const char
  210. //-----------------------------------------------------------------------------
  211. const char *CExpression::GetBitmapCheckSum()
  212. {
  213. CRC32_t crc = GetBitmapCRC();
  214. // Create string name out of binary data
  215. static char hex[ 9 ];
  216. Q_binarytohex( (byte *)&crc, sizeof( crc ), hex, sizeof( hex ) );
  217. return hex;
  218. }
  219. //-----------------------------------------------------------------------------
  220. // Purpose:
  221. // Output : const char
  222. //-----------------------------------------------------------------------------
  223. const char *CExpression::GetBitmapFilename( int modelindex )
  224. {
  225. static char filename[ 256 ] = { 0 };
  226. char const *classname = "error";
  227. CExpClass *cl = GetExpressionClass();
  228. if ( cl )
  229. {
  230. classname = cl->GetBaseName();
  231. }
  232. char modelName[512], modelNameTemp[512];
  233. Q_strncpy( modelNameTemp, models->GetModelName( modelindex ), sizeof( modelNameTemp ) );
  234. char const *in = modelNameTemp;
  235. char *out = modelName;
  236. while ( *in )
  237. {
  238. if ( V_isalnum( *in ) ||
  239. *in == '_' ||
  240. *in == '\\' ||
  241. *in == '/' ||
  242. *in == '.' ||
  243. *in == ':' )
  244. {
  245. *out++ = *in;
  246. }
  247. in++;
  248. }
  249. *out = 0;
  250. sprintf( filename, "expressions/%s/%s/%s.bmp", modelName, classname, GetBitmapCheckSum() );
  251. Q_FixSlashes( filename );
  252. strlwr( filename );
  253. CreatePath( filename );
  254. return filename;
  255. }
  256. void CExpression::CreateNewBitmap( int modelindex )
  257. {
  258. MatSysWindow *pWnd = g_pMatSysWindow;
  259. if ( !pWnd )
  260. return;
  261. StudioModel *model = models->GetStudioModel( modelindex );
  262. if ( !model )
  263. return;
  264. CStudioHdr *hdr = models->GetStudioHeader( modelindex );
  265. if ( !hdr )
  266. return;
  267. char filename[ 256 ];
  268. strcpy( filename, GetBitmapFilename( modelindex ) );
  269. if ( !Q_strstr( filename, ".bmp" ) )
  270. return;
  271. models->CreateNewBitmap( modelindex, filename, 0, 128, true, this, &m_Bitmap[ modelindex ] );
  272. }
  273. //-----------------------------------------------------------------------------
  274. // Purpose:
  275. // Input : *exp -
  276. //-----------------------------------------------------------------------------
  277. void CExpression::PushUndoInformation( void )
  278. {
  279. SetModified( true );
  280. // A real change to the data wipes out the redo counters
  281. WipeRedoInformation();
  282. CExpUndoInfo *newundo = new CExpUndoInfo;
  283. memcpy( newundo->setting, setting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  284. memset( newundo->redosetting, 0, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  285. memcpy( newundo->weight, weight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  286. memset( newundo->redoweight, 0, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  287. newundo->counter = g_counter++;
  288. undo.AddToHead( newundo );
  289. Assert( m_nUndoCurrent == 0 );
  290. }
  291. //-----------------------------------------------------------------------------
  292. // Purpose:
  293. // Input : *exp -
  294. //-----------------------------------------------------------------------------
  295. void CExpression::PushRedoInformation( void )
  296. {
  297. Assert( undo.Count() >= 1 );
  298. CExpUndoInfo *redo = undo[ 0 ];
  299. memcpy( redo->redosetting, setting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  300. memcpy( redo->redoweight, weight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  301. }
  302. //-----------------------------------------------------------------------------
  303. // Purpose:
  304. // Input : *exp -
  305. //-----------------------------------------------------------------------------
  306. void CExpression::Undo( void )
  307. {
  308. if ( !CanUndo() )
  309. return;
  310. Assert( m_nUndoCurrent < undo.Count() );
  311. CExpUndoInfo *u = undo[ m_nUndoCurrent++ ];
  312. Assert( u );
  313. memcpy( setting, u->setting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  314. memcpy( weight, u->weight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  315. }
  316. //-----------------------------------------------------------------------------
  317. // Purpose:
  318. // Input : *exp -
  319. //-----------------------------------------------------------------------------
  320. void CExpression::Redo( void )
  321. {
  322. if ( !CanRedo() )
  323. return;
  324. Assert( m_nUndoCurrent >= 1 );
  325. Assert( m_nUndoCurrent <= undo.Count() );
  326. CExpUndoInfo *u = undo[ --m_nUndoCurrent ];
  327. Assert( u );
  328. memcpy( setting, u->redosetting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  329. memcpy( weight, u->redoweight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  330. }
  331. //-----------------------------------------------------------------------------
  332. // Purpose:
  333. // Input : *exp -
  334. //-----------------------------------------------------------------------------
  335. void CExpression::WipeRedoInformation( void )
  336. {
  337. // Wipe out all stuff newer then m_nUndoCurrent
  338. int level = 0;
  339. while ( level < m_nUndoCurrent )
  340. {
  341. CExpUndoInfo *u = undo[ 0 ];
  342. undo.Remove( 0 );
  343. Assert( u );
  344. delete u;
  345. level++;
  346. }
  347. m_nUndoCurrent = 0;
  348. }
  349. //-----------------------------------------------------------------------------
  350. // Purpose: Revert to last saved state
  351. //-----------------------------------------------------------------------------
  352. void CExpression::Revert( void )
  353. {
  354. SetDirty( false );
  355. if ( undo.Count() <= 0 )
  356. return;
  357. // Go back to original data
  358. CExpUndoInfo *u = undo[ undo.Count() - 1 ];
  359. Assert( u );
  360. memcpy( setting, u->setting, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  361. memcpy( weight, u->weight, GLOBAL_STUDIO_FLEX_CONTROL_COUNT * sizeof( float ) );
  362. ResetUndo();
  363. }
  364. //-----------------------------------------------------------------------------
  365. // Purpose:
  366. // Output : CExpClass
  367. //-----------------------------------------------------------------------------
  368. CExpClass *CExpression::GetExpressionClass( void )
  369. {
  370. CExpClass *cl = expressions->FindClass( expressionclass, false );
  371. if ( !cl )
  372. {
  373. Assert( cl );
  374. }
  375. return cl;
  376. }
  377. //-----------------------------------------------------------------------------
  378. // Purpose:
  379. // Input : *classname -
  380. //-----------------------------------------------------------------------------
  381. void CExpression::SetExpressionClass( char const *classname )
  382. {
  383. strcpy( expressionclass, classname );
  384. }