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.

379 lines
8.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "wavefile.h"
  8. #include "sentence.h"
  9. #include "iscenemanagersound.h"
  10. #include "SoundEmitterSystem/isoundemittersystembase.h"
  11. #include "snd_wave_source.h"
  12. #include "cmdlib.h"
  13. #include "workspacemanager.h"
  14. #include "vcdfile.h"
  15. #include "workspacebrowser.h"
  16. #include "multiplerequest.h"
  17. #include "UtlBuffer.h"
  18. #include "scenemanager_tools.h"
  19. //-----------------------------------------------------------------------------
  20. // Purpose:
  21. // Input : *name -
  22. //-----------------------------------------------------------------------------
  23. CWaveFile::CWaveFile( CVCDFile *vcd, CSoundEntry *se, char const *filename )
  24. : m_pOwner( vcd ), m_pOwnerSE( se )
  25. {
  26. m_bSentenceLoaded = false;
  27. m_Sentence.Reset();
  28. Q_strncpy( m_szName, filename, sizeof( m_szName ) );
  29. m_pWaveFile = NULL;
  30. Q_snprintf( m_szFileName, sizeof( m_szFileName ), "sound/%s", filename );
  31. }
  32. CWaveFile::~CWaveFile()
  33. {
  34. }
  35. //-----------------------------------------------------------------------------
  36. // Purpose:
  37. // Output : int
  38. //-----------------------------------------------------------------------------
  39. int CWaveFile::GetLanguageId()
  40. {
  41. return GetWorkspaceManager()->GetLanguageId();
  42. }
  43. void CWaveFile::EnsureSentence()
  44. {
  45. if ( m_bSentenceLoaded )
  46. return;
  47. m_bSentenceLoaded = true;
  48. if ( m_szFileName[ 0 ] )
  49. {
  50. SceneManager_LoadSentenceFromWavFile( m_szFileName, m_Sentence );
  51. }
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Purpose:
  55. // Output : Returns true on success, false on failure.
  56. //-----------------------------------------------------------------------------
  57. bool CWaveFile::HasLoadedSentenceInfo() const
  58. {
  59. return m_bSentenceLoaded;
  60. }
  61. CVCDFile *CWaveFile::GetOwnerVCDFile()
  62. {
  63. return m_pOwner;
  64. }
  65. CSoundEntry *CWaveFile::GetOwnerSoundEntry()
  66. {
  67. return m_pOwnerSE;
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Purpose:
  71. // Input : *name -
  72. //-----------------------------------------------------------------------------
  73. void CWaveFile::SetName( char const *filename )
  74. {
  75. if ( !Q_stricmp( m_szName, filename ) )
  76. return;
  77. Q_strncpy( m_szName, filename, sizeof( m_szName ) );
  78. Q_snprintf( m_szFileName, sizeof( m_szFileName ), "sound/%s", filename );
  79. if ( m_szFileName[ 0 ] )
  80. {
  81. SceneManager_LoadSentenceFromWavFile( m_szFileName, m_Sentence );
  82. m_bSentenceLoaded = true;
  83. }
  84. }
  85. char const *CWaveFile::GetName() const
  86. {
  87. return m_szName;
  88. }
  89. char const *CWaveFile::GetFileName() const
  90. {
  91. return m_szFileName;
  92. }
  93. char const *CWaveFile::GetSentenceText()
  94. {
  95. EnsureSentence();
  96. return m_Sentence.GetText();
  97. }
  98. void CWaveFile::SetSentenceText( char const *newText )
  99. {
  100. EnsureSentence();
  101. if ( !Q_stricmp( GetSentenceText(), newText ) )
  102. return;
  103. if ( !IsCheckedOut() )
  104. {
  105. int retval = MultipleRequest( va( "Check out '%s'?", GetFileName() ) );
  106. if ( retval != 0 )
  107. return;
  108. VSS_Checkout( GetFileName() );
  109. }
  110. m_Sentence.SetText( newText );
  111. SceneManager_SaveSentenceToWavFile( GetFileName(), m_Sentence );
  112. }
  113. void CWaveFile::ValidateTree( mxTreeView *tree, mxTreeViewItem* parent )
  114. {
  115. }
  116. void CWaveFile::Play()
  117. {
  118. if ( !m_pWaveFile )
  119. {
  120. m_pWaveFile = sound->FindOrAddSound( m_szFileName );
  121. }
  122. if ( !m_pWaveFile )
  123. {
  124. Con_Printf( "Can't play '%s', no wave file loaded\n", GetFileName() );
  125. return;
  126. }
  127. Con_Printf( "Playing '%s' : '%s'\n", GetFileName(), GetSentenceText() );
  128. CAudioMixer *temp;
  129. sound->PlaySound( m_pWaveFile, &temp );
  130. }
  131. bool CWaveFile::GetVoiceDuck()
  132. {
  133. EnsureSentence();
  134. return m_Sentence.GetVoiceDuck();
  135. }
  136. void CWaveFile::SetVoiceDuck( bool duck )
  137. {
  138. EnsureSentence();
  139. if ( GetVoiceDuck() == duck )
  140. return;
  141. m_Sentence.SetVoiceDuck( duck );
  142. if ( !IsCheckedOut() )
  143. {
  144. int retval = MultipleRequest( va( "Check out '%s'?", GetFileName() ) );
  145. if ( retval != 0 )
  146. return;
  147. VSS_Checkout( GetFileName() );
  148. }
  149. SceneManager_SaveSentenceToWavFile( GetFileName(), m_Sentence );
  150. }
  151. void CWaveFile::ToggleVoiceDucking()
  152. {
  153. EnsureSentence();
  154. m_Sentence.SetVoiceDuck( !m_Sentence.GetVoiceDuck() );
  155. if ( !IsCheckedOut() )
  156. {
  157. int retval = MultipleRequest( va( "Check out '%s'?", GetFileName() ) );
  158. if ( retval != 0 )
  159. return;
  160. VSS_Checkout( GetFileName() );
  161. }
  162. SceneManager_SaveSentenceToWavFile( GetFileName(), m_Sentence );
  163. }
  164. bool CWaveFile::IsCheckedOut() const
  165. {
  166. return filesystem->IsFileWritable( GetFileName() );
  167. }
  168. int CWaveFile::GetIconIndex() const
  169. {
  170. if ( IsCheckedOut() )
  171. {
  172. return IMAGE_WAV_CHECKEDOUT;
  173. }
  174. else
  175. {
  176. return IMAGE_WAV;
  177. }
  178. }
  179. void CWaveFile::Checkout(bool updatestateicons /*= true*/)
  180. {
  181. VSS_Checkout( GetFileName(), updatestateicons );
  182. }
  183. void CWaveFile::Checkin(bool updatestateicons /*= true*/)
  184. {
  185. VSS_Checkin( GetFileName(), updatestateicons );
  186. }
  187. void CWaveFile::MoveChildUp( ITreeItem *child )
  188. {
  189. }
  190. void CWaveFile::MoveChildDown( ITreeItem *child )
  191. {
  192. }
  193. void CWaveFile::SetDirty( bool dirty )
  194. {
  195. if ( GetOwnerVCDFile() )
  196. {
  197. GetOwnerVCDFile()->SetDirty( dirty );
  198. }
  199. }
  200. bool CWaveFile::IsChildFirst( ITreeItem *child )
  201. {
  202. return false;
  203. }
  204. bool CWaveFile::IsChildLast( ITreeItem *child )
  205. {
  206. return false;
  207. }
  208. //-----------------------------------------------------------------------------
  209. // Purpose:
  210. // Input : sentence -
  211. //-----------------------------------------------------------------------------
  212. void CWaveFile::SetThreadLoadedSentence( CSentence& sentence )
  213. {
  214. if ( m_bSentenceLoaded )
  215. return;
  216. m_bSentenceLoaded = true;
  217. m_Sentence = sentence;
  218. }
  219. #define WORD_DATA_EXTENSION ".txt"
  220. //-----------------------------------------------------------------------------
  221. // Purpose:
  222. // Input : *tempfile -
  223. //-----------------------------------------------------------------------------
  224. void CWaveFile::ExportValveDataChunk( char const *tempfile )
  225. {
  226. EnsureSentence();
  227. if ( m_Sentence.m_Words.Count() <= 0 )
  228. {
  229. Con_ColorPrintf( ERROR_R, ERROR_G, ERROR_B, "CWaveFile::ExportValveDataChunk: Sentence has no word data\n" );
  230. return;
  231. }
  232. SafeCreatePath( va( "%s%s", SceneManager_GetGameDirectory(), (char *)tempfile ) );
  233. FileHandle_t fh = filesystem->Open( tempfile, "wb" );
  234. if ( !fh )
  235. {
  236. Con_ColorPrintf( ERROR_R, ERROR_G, ERROR_B, "CWaveFile::ExportValveDataChunk: Unable to write to %s (read-only?)\n", tempfile );
  237. return;
  238. }
  239. else
  240. {
  241. // Buffer and dump data
  242. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  243. m_Sentence.SaveToBuffer( buf );
  244. filesystem->Write( buf.Base(), buf.TellPut(), fh );
  245. filesystem->Close(fh);
  246. Con_Printf( "Exported %i words to %s\n", m_Sentence.m_Words.Count(), tempfile );
  247. }
  248. }
  249. //-----------------------------------------------------------------------------
  250. // Purpose:
  251. // Input : *tempfile -
  252. //-----------------------------------------------------------------------------
  253. void CWaveFile::ImportValveDataChunk( char const *tempfile )
  254. {
  255. EnsureSentence();
  256. FileHandle_t fh = filesystem->Open( tempfile, "rb" );
  257. if ( !fh )
  258. {
  259. Con_ColorPrintf( ERROR_R, ERROR_G, ERROR_B, "CWaveFile::ImportValveDataChunk: Unable to read from %s\n", tempfile );
  260. return;
  261. }
  262. int len = filesystem->Size( fh );
  263. if ( len <= 4 )
  264. {
  265. Con_ColorPrintf( ERROR_R, ERROR_G, ERROR_B, "CWaveFile::ImportValveDataChunk: File %s has length 0\n", tempfile );
  266. return;
  267. }
  268. CSentence newSentence;
  269. unsigned char *buf = new unsigned char[ len + 1 ];
  270. filesystem->Read( buf, len, fh );
  271. filesystem->Close( fh );
  272. newSentence.InitFromDataChunk( (void *)( buf ), len );
  273. delete[] buf;
  274. // See if we can write it out...
  275. if ( !IsCheckedOut() )
  276. {
  277. int retval = MultipleRequest( va( "Check out '%s'?", GetFileName() ) );
  278. if ( retval != 0 )
  279. return;
  280. VSS_Checkout( GetFileName() );
  281. }
  282. if ( !IsCheckedOut() )
  283. {
  284. MakeFileWriteable( GetFileName() );
  285. Con_Printf( "Unable to check out %s, forcing it to be writable instead!\n", GetFileName() );
  286. }
  287. Con_Printf( "Imported %i words from %s\n", newSentence.m_Words.Count(), tempfile );
  288. m_Sentence = newSentence;
  289. SceneManager_SaveSentenceToWavFile( GetFileName(), m_Sentence );
  290. }
  291. void CWaveFile::GetPhonemeExportFile( char *path, int maxlen )
  292. {
  293. char relative[ 512 ];
  294. strcpy( relative, GetFileName() );
  295. Q_StripExtension( relative, relative, sizeof( relative ) );
  296. Q_DefaultExtension( relative, WORD_DATA_EXTENSION, sizeof( relative ) );
  297. Q_snprintf( path, maxlen, "phonemes/%s", relative );
  298. Q_FixSlashes( path );
  299. }