|
|
//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#include "cbase.h"
#include <windows.h>
#include "resource.h"
#include "wavefile.h"
#include "wavebrowser.h"
#include "SoundEmitterSystem/isoundemittersystembase.h"
#include "ifaceposersound.h"
#include "snd_wave_source.h"
#include "filesystem.h"
#include "tabwindow.h"
#include "inputproperties.h"
#include "choreowidgetdrawhelper.h"
#include "ifileloader.h"
#include "tier2/riff.h"
#include "UtlBuffer.h"
#include "ChoreoEvent.h"
CWaveBrowser *g_pWaveBrowser = NULL;
//-----------------------------------------------------------------------------
// Purpose: Implements the RIFF i/o interface on stdio
//-----------------------------------------------------------------------------
class StdIOReadBinary : public IFileReadBinary { public: FileHandle_t open( const char *pFileName ) { return filesystem->Open( pFileName, "rb" ); }
int read( void *pOutput, int size, FileHandle_t file ) { if ( !file ) return 0;
return filesystem->Read( pOutput, size, file ); }
void seek( FileHandle_t file, int pos ) { if ( !file ) return;
filesystem->Seek( file, pos, FILESYSTEM_SEEK_HEAD ); }
unsigned int tell( FileHandle_t file ) { if ( !file ) return 0;
return filesystem->Tell( file ); }
unsigned int size( FileHandle_t file ) { if ( !file ) return 0;
return filesystem->Size( file ); }
void close( FileHandle_t file ) { if ( !file ) return;
filesystem->Close( file ); } };
class StdIOWriteBinary : public IFileWriteBinary { public: FileHandle_t create( const char *pFileName ) { return filesystem->Open( pFileName, "wb" ); }
int write( void *pData, int size, FileHandle_t file ) { return filesystem->Write( pData, size, file ); }
void close( FileHandle_t file ) { filesystem->Close( file ); }
void seek( FileHandle_t file, int pos ) { filesystem->Seek( file, pos, FILESYSTEM_SEEK_HEAD ); }
unsigned int tell( FileHandle_t file ) { return filesystem->Tell( file ); } };
static StdIOReadBinary io_in; static StdIOWriteBinary io_out;
#define RIFF_WAVE MAKEID('W','A','V','E')
#define WAVE_FMT MAKEID('f','m','t',' ')
#define WAVE_DATA MAKEID('d','a','t','a')
#define WAVE_FACT MAKEID('f','a','c','t')
#define WAVE_CUE MAKEID('c','u','e',' ')
//-----------------------------------------------------------------------------
// Purpose:
// Input : &walk -
//-----------------------------------------------------------------------------
static void SceneManager_ParseSentence( CSentence& sentence, IterateRIFF &walk ) { CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
buf.EnsureCapacity( walk.ChunkSize() ); walk.ChunkRead( buf.Base() ); buf.SeekPut( CUtlBuffer::SEEK_HEAD, walk.ChunkSize() );
sentence.InitFromDataChunk( buf.Base(), buf.TellPut() ); }
bool SceneManager_LoadSentenceFromWavFileUsingIO( char const *wavfile, CSentence& sentence, IFileReadBinary& io ) { sentence.Reset();
InFileRIFF riff( wavfile, io );
// UNDONE: Don't use printf to handle errors
if ( riff.RIFFName() != RIFF_WAVE ) { return false; }
// set up the iterator for the whole file (root RIFF is a chunk)
IterateRIFF walk( riff, riff.RIFFSize() );
// This chunk must be first as it contains the wave's format
// break out when we've parsed it
bool found = false; while ( walk.ChunkAvailable() && !found ) { switch( walk.ChunkName() ) { case WAVE_VALVEDATA: { found = true; SceneManager_ParseSentence( sentence, walk ); } break; } walk.ChunkNext(); }
return true; }
bool SceneManager_LoadSentenceFromWavFile( char const *wavfile, CSentence& sentence ) { return SceneManager_LoadSentenceFromWavFileUsingIO( wavfile, sentence, io_in ); }
enum { // Controls
IDC_SB_LISTVIEW = 101, IDC_SB_FILETREE,
// Messages
IDC_SB_PLAY = 1000, };
enum { COL_WAV = 0, COL_DUCKED, COL_PHONEMES, COL_SENTENCE };
class CWaveList : public mxListView { public: CWaveList( mxWindow *parent, int id = 0 ) : mxListView( parent, 0, 0, 0, 0, id ) { // Add column headers
insertTextColumn( COL_WAV, 300, "WAV" ); insertTextColumn( COL_DUCKED, 50, "Ducked" ); insertTextColumn( COL_PHONEMES, 120, "Words [ Phonemes ]" ); insertTextColumn( COL_SENTENCE, 300, "Sentence Text" ); } };
class CWaveFileTree : public mxTreeView { public: CWaveFileTree( mxWindow *parent, int id = 0 ) : mxTreeView( parent, 0, 0, 0, 0, id ), m_Paths( 0, 0, FileTreeLessFunc ) { }
void Clear() { removeAll(); m_Paths.RemoveAll(); }
void FindOrAddSubdirectory( char const *subdir ) { FileTreePath fp; Q_strcpy( fp.path, subdir );
if ( m_Paths.Find( fp ) != m_Paths.InvalidIndex() ) return;
m_Paths.Insert( fp ); }
mxTreeViewItem *FindOrAddChildItem( mxTreeViewItem *parent, char const *child ) { mxTreeViewItem *p = getFirstChild( parent ); if ( !p ) { return add( parent, child ); }
while ( p ) { if ( !Q_stricmp( getLabel( p ), child ) ) return p;
p = getNextChild( p ); }
return add( parent, child ); }
void _PopulateTree( int pathId, char const *path ) { char sz[ 512 ]; Q_strcpy( sz, path ); char *p = sz;
// Start at root
mxTreeViewItem *cur = NULL;
// Tokenize path
while ( p && p[0] ) { char *slash = Q_strstr( p, "/" ); if ( !slash ) { slash = Q_strstr( p, "\\" ); }
char *check = p;
if ( slash ) { *slash = 0;
// see if a child of current already exists with this name
p = slash + 1; } else { p = NULL; }
Assert( check );
cur = FindOrAddChildItem( cur, check ); }
setUserData( cur, (void *)pathId ); }
char const *GetSelectedPath( void ) { mxTreeViewItem *tvi = getSelectedItem(); unsigned int id = (unsigned int)getUserData( tvi );
if ( id < 0 || id >= m_Paths.Count() ) { Assert( 0 ); return ""; } return m_Paths[ id ].path; }
void PopulateTree() { int i; for ( i = m_Paths.FirstInorder(); i != m_Paths.InvalidIndex(); i = m_Paths.NextInorder( i ) ) { _PopulateTree( i, m_Paths[ i ].path ); }
mxTreeViewItem *p = getFirstChild( NULL ); setOpen( p, true ); }
struct FileTreePath { char path[ MAX_PATH ]; };
static bool FileTreeLessFunc( const FileTreePath &lhs, const FileTreePath &rhs ) { return Q_stricmp( lhs.path, rhs.path ) < 0; }
CUtlRBTree< FileTreePath, int > m_Paths; }; #pragma optimize( "", off )
class CWaveOptionsWindow : public mxWindow { typedef mxWindow BaseClass; public: enum { IDC_PLAYSOUND = 1000, IDC_STOP_SOUNDS, IDC_SEARCH, IDC_CANCELSEARCH, };
CWaveOptionsWindow( CWaveBrowser *browser ) : BaseClass( browser, 0, 0, 0, 0 ), m_pBrowser( browser ) { FacePoser_AddWindowStyle( this, WS_CLIPSIBLINGS | WS_CLIPCHILDREN );
m_szSearchString[0]=0;
m_pPlay = new mxButton( this, 0, 0, 0, 0, "Play", IDC_PLAYSOUND ); m_pStopSounds = new mxButton( this, 0, 0, 0, 0, "Stop Sounds", IDC_STOP_SOUNDS ); m_pSearch = new mxLineEdit( this, 0, 0, 0, 0, "", IDC_SEARCH );
m_pCancelSearch = new mxButton( this, 0, 0, 0, 0, "Cancel", IDC_CANCELSEARCH ); } bool PaintBackground( void ) { redraw(); return false; } virtual void redraw() { CChoreoWidgetDrawHelper drawHelper( this, RGBToColor( GetSysColor( COLOR_BTNFACE ) ) ); } virtual int handleEvent( mxEvent *event ) { int iret = 0; switch ( event->event ) { default: break; case mxEvent::Size: { iret = 1; int split = 120; int x = 1; m_pPlay->setBounds( x, 1, split, h2() - 2 ); x += split + 10; m_pStopSounds->setBounds( x, 1, split, h2()-2 ); x += split + 10;
m_pCancelSearch->setBounds( x, 1, split, h2() - 2 ); x += split + 10; m_pSearch->setBounds( x, 0, split * 3, h2() - 1 ); x += split * 3 + 10; } break; case mxEvent::KeyDown: switch ( event->action ) { default: break; case IDC_SEARCH: { if ( event->event == mxEvent::KeyDown ) { OnSearch(); } iret = 1; }; break; } break; case mxEvent::Action: { switch ( event->action ) { case IDC_STOP_SOUNDS: { iret = 1; sound->StopAll(); } break; case IDC_SEARCH: iret = 1; break; case IDC_PLAYSOUND: { iret = 1; m_pBrowser->OnPlay(); } break; case IDC_CANCELSEARCH: { iret = 1; OnCancelSearch(); } break; default: break; } } break; } return iret; } char const *GetSearchString() { return m_szSearchString; }
void OnSearch() { m_pSearch->getText( m_szSearchString, sizeof( m_szSearchString ) );
m_pBrowser->OnSearch(); }
void OnCancelSearch() { m_szSearchString[ 0 ] = 0; m_pSearch->clear();
m_pBrowser->OnCancelSearch(); }
private: mxButton *m_pStopSounds; mxButton *m_pPlay; mxLineEdit *m_pSearch; mxButton *m_pCancelSearch; CWaveBrowser *m_pBrowser;
char m_szSearchString[ 256 ]; };
#pragma optimize( "", on )
//-----------------------------------------------------------------------------
// Purpose:
// Input : *parent -
//-----------------------------------------------------------------------------
CWaveBrowser::CWaveBrowser( mxWindow *parent ) : IFacePoserToolWindow( "WaveBrowser", "Waves" ), mxWindow( parent, 0, 0, 0, 0 ) { SetAutoProcess( false );
m_bTextSearch = false; m_nPrevProcessed = -1;
m_pListView = new CWaveList( this, IDC_SB_LISTVIEW ); m_pOptions = new CWaveOptionsWindow( this ); m_pFileTree = new CWaveFileTree( this, IDC_SB_FILETREE );
//HIMAGELIST list = CreateImageList();
// Associate the image list with the tree-view control.
//m_pListView->setImageList( (void *)list );
LoadAllSounds();
PopulateTree( NULL ); }
#define CX_ICON 16
#define CY_ICON 16
HIMAGELIST CWaveBrowser::CreateImageList() { HIMAGELIST list; list = ImageList_Create( CX_ICON, CY_ICON, FALSE, NUM_IMAGES, 0 );
// Load the icon resources, and add the icons to the image list.
HICON hicon; int slot; #if defined( _DEBUG )
int c = 0; #endif
/*
hicon = LoadIcon( GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_WORKSPACE)); slot = ImageList_AddIcon(list, hicon); Assert( slot == c++ ); DeleteObject( hicon );
hicon = LoadIcon( GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_WORKSPACE_CHECKEDOUT)); slot = ImageList_AddIcon(list, hicon); Assert( slot == c++ ); DeleteObject( hicon );
hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_PROJECT)); slot = ImageList_AddIcon(list, hicon); Assert( slot == c++ ); DeleteObject( hicon );
hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_PROJECT_CHECKEDOUT)); slot = ImageList_AddIcon(list, hicon); Assert( slot == c++ ); DeleteObject( hicon );
hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_SCENE)); slot = ImageList_AddIcon(list, hicon); Assert( slot == c++ ); DeleteObject( hicon ); */
// hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_SCENE_CHECKEDOUT));
// slot = ImageList_AddIcon(list, hicon);
// Assert( slot == c++ );
// DeleteObject( hicon );
/*
hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_VCD)); slot = ImageList_AddIcon(list, hicon); Assert( slot == c++ ); DeleteObject( hicon );
hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_VCD_CHECKEDOUT )); slot = ImageList_AddIcon(list, hicon); Assert( slot == c++ ); DeleteObject( hicon ); */
hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_WAV)); slot = ImageList_AddIcon(list, hicon); Assert( slot == c++ ); DeleteObject( hicon );
/*
hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_WAV_CHECKEDOUT)); slot = ImageList_AddIcon(list, hicon); Assert( slot == c++ ); DeleteObject( hicon );
hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_SPEAK)); slot = ImageList_AddIcon(list, hicon); Assert( slot == c++ ); DeleteObject( hicon );
hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_SPEAK_CHECKEDOUT)); slot = ImageList_AddIcon(list, hicon); Assert( slot == c++ ); DeleteObject( hicon ); */
return list; }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWaveBrowser::OnDelete() { RemoveAllSounds(); }
//-----------------------------------------------------------------------------
// Purpose:
// Input : *event -
// Output : int
//-----------------------------------------------------------------------------
int CWaveBrowser::handleEvent( mxEvent *event ) { int iret = 0;
if ( HandleToolEvent( event ) ) { return iret; }
switch ( event->event ) { default: break; case mxEvent::Action: { iret = 1; switch ( event->action ) { default: { iret = 0; } break; case IDC_SB_LISTVIEW: { SetActiveTool( this );
bool rightmouse = ( event->flags == mxEvent::RightClicked ) ? true : false; bool doubleclicked = ( event->flags == mxEvent::DoubleClicked ) ? true : false;
if ( rightmouse ) { ShowContextMenu(); } else if ( doubleclicked ) { if ( m_pListView->getNumSelected() == 1 ) { int index = m_pListView->getNextSelectedItem( -1 ); if ( index >= 0 ) { CWaveFile *wav = (CWaveFile *)m_pListView->getUserData( index, 0 ); if ( wav ) { wav->Play(); } } } } } break; case IDC_SB_FILETREE: { SetActiveTool( this );
PopulateTree( m_pFileTree->GetSelectedPath() ); } break; case IDC_SB_PLAY: { OnPlay(); } break; } } break; case mxEvent::Size: { int optionsh = 20;
m_pOptions->setBounds( 0, 0, w2(), optionsh );
int filetreewidth = 175;
m_pFileTree->setBounds( 0, optionsh, filetreewidth, h2() - optionsh ); m_pListView->setBounds( filetreewidth, optionsh, w2() - filetreewidth, h2() - optionsh );
iret = 1; } break; case mxEvent::Close: { iret = 1; } break; }
return iret; }
static bool NameLessFunc( CWaveFile *const& name1, CWaveFile *const& name2 ) { if ( Q_stricmp( name1->GetName(), name2->GetName() ) < 0 ) return true; return false; }
#define SOUND_PREFIX_LEN 6
//-----------------------------------------------------------------------------
// Finds all .wav files in a particular directory
//-----------------------------------------------------------------------------
bool CWaveBrowser::LoadWaveFilesInDirectory( CUtlDict< CWaveFile *, int >& soundlist, char const* pDirectoryName, int nDirectoryNameLen ) { Assert( Q_strnicmp( pDirectoryName, "sound", 5 ) == 0 );
char *pWildCard; pWildCard = ( char * )stackalloc( nDirectoryNameLen + 7 ); Q_snprintf( pWildCard, nDirectoryNameLen + 7, "%s/*.wav", pDirectoryName );
if ( !filesystem ) { return false; }
FileFindHandle_t findHandle; const char *pFileName = filesystem->FindFirst( pWildCard, &findHandle ); while( pFileName ) { if( !filesystem->FindIsDirectory( findHandle ) ) { // Strip off the 'sound/' part of the name.
char *pFileNameWithPath; int nAllocSize = nDirectoryNameLen + Q_strlen(pFileName) + 2; pFileNameWithPath = (char *)stackalloc( nAllocSize ); Q_snprintf( pFileNameWithPath, nAllocSize, "%s/%s", &pDirectoryName[SOUND_PREFIX_LEN], pFileName ); Q_strnlwr( pFileNameWithPath, nAllocSize );
CWaveFile *wav = new CWaveFile( pFileNameWithPath ); soundlist.Insert( pFileNameWithPath, wav );
/*
if ( !(soundlist.Count() % 500 ) ) { Con_Printf( "CWaveBrowser: loaded %i sounds\n", soundlist.Count() ); } */ } pFileName = filesystem->FindNext( findHandle ); }
m_pFileTree->FindOrAddSubdirectory( &pDirectoryName[ SOUND_PREFIX_LEN ] );
filesystem->FindClose( findHandle ); return true; }
bool CWaveBrowser::InitDirectoryRecursive( CUtlDict< CWaveFile *, int >& soundlist, char const* pDirectoryName ) { // Compute directory name length
int nDirectoryNameLen = Q_strlen( pDirectoryName );
if (!LoadWaveFilesInDirectory( soundlist, pDirectoryName, nDirectoryNameLen ) ) return false;
char *pWildCard = ( char * )stackalloc( nDirectoryNameLen + 4 ); strcpy(pWildCard, pDirectoryName); strcat(pWildCard, "/*."); int nPathStrLen = nDirectoryNameLen + 1;
FileFindHandle_t findHandle; const char *pFileName = filesystem->FindFirst( pWildCard, &findHandle ); while( pFileName ) { if ((pFileName[0] != '.') || (pFileName[1] != '.' && pFileName[1] != 0)) { if( filesystem->FindIsDirectory( findHandle ) ) { int fileNameStrLen = Q_strlen( pFileName ); char *pFileNameWithPath = ( char * )stackalloc( nPathStrLen + fileNameStrLen + 1 ); memcpy( pFileNameWithPath, pWildCard, nPathStrLen ); pFileNameWithPath[nPathStrLen] = '\0'; strcat( pFileNameWithPath, pFileName );
if (!InitDirectoryRecursive( soundlist, pFileNameWithPath )) return false; } } pFileName = filesystem->FindNext( findHandle ); }
return true; }
void CWaveBrowser::LoadAllSounds() { RemoveAllSounds();
Con_Printf( "Building list of all .wavs in sound/ folder\n" );
InitDirectoryRecursive( m_AllSounds, "sound" );
m_pFileTree->PopulateTree(); }
void CWaveBrowser::RemoveAllSounds() { int c = m_AllSounds.Count(); for ( int i = 0; i < c; i++ ) { CWaveFile *wav = m_AllSounds[ i ]; delete wav; }
m_AllSounds.RemoveAll(); m_Scripts.RemoveAll(); m_CurrentSelection.RemoveAll();
m_pFileTree->Clear(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWaveBrowser::PopulateTree( char const *subdirectory ) { int i;
CUtlRBTree< CWaveFile *, int > m_Sorted( 0, 0, NameLessFunc ); bool check_load_sentence_data = false;
char const *texttofind = NULL;
if ( m_bTextSearch ) { subdirectory = NULL; texttofind = GetSearchString(); }
int len = 0; if ( subdirectory ) { len = Q_strlen( subdirectory ); check_load_sentence_data = ( Q_strstr( subdirectory, "/" ) || subdirectory[0] ) ? true : false; }
int c = m_AllSounds.Count(); for ( i = 0; i < c; i++ ) { CWaveFile *wav = m_AllSounds[ i ]; char const *name = wav->GetName();
if ( subdirectory ) { if ( Q_strnicmp( subdirectory, wav->GetName(), len ) ) continue; }
if ( m_bTextSearch && texttofind ) { if ( !Q_stristr( name, texttofind ) ) continue; }
m_Sorted.Insert( wav ); }
char prevSelectedName[ 512 ]; prevSelectedName[ 0 ] = 0; if ( m_pListView->getNumSelected() == 1 ) { int selectedItem = m_pListView->getNextSelectedItem( 0 ); if ( selectedItem >= 0 ) { // Grab wave name of previously selected item
Q_strcpy( prevSelectedName, m_pListView->getLabel( selectedItem, 0 ) ); } }
// Repopulate tree
m_pListView->removeAll();
int loadcount = 0;
m_pListView->setDrawingEnabled( false );
int selectedSlot = -1;
CUtlVector< CWaveFile * > list;
for ( i = m_Sorted.FirstInorder(); i != m_Sorted.InvalidIndex(); i = m_Sorted.NextInorder( i ) ) { CWaveFile *wav = m_Sorted[ i ]; char const *name = wav->GetName();
int slot = m_pListView->add( name );
if ( !Q_stricmp( prevSelectedName, name ) ) { selectedSlot = slot; }
if ( ( check_load_sentence_data || m_bTextSearch ) && !wav->HasLoadedSentenceInfo() && !wav->IsAsyncLoading() ) { wav->SetAsyncLoading( true ); list.AddToTail( wav ); }
// m_pListView->setImage( slot, COL_WAV, wav->GetIconIndex() );
m_pListView->setUserData( slot, COL_WAV, (void *)wav );
if ( wav->HasLoadedSentenceInfo() ) { m_pListView->setLabel( slot, COL_DUCKED, wav->GetVoiceDuck() ? "yes" : "no" ); m_pListView->setLabel( slot, COL_PHONEMES, wav->GetPhonemeCount() || wav->GetWordCount() ? va( "%i [ %i ]", wav->GetWordCount(), wav->GetPhonemeCount() ) : "" ); m_pListView->setLabel( slot, COL_SENTENCE, wav->GetSentenceText() ); } else { m_pListView->setLabel( slot, COL_SENTENCE, "(loading...)" ); }
++loadcount; }
m_pListView->setDrawingEnabled( true );
if ( selectedSlot != -1 ) { m_pListView->setSelected( selectedSlot, true ); m_pListView->scrollToItem( selectedSlot ); }
if ( list.Count() > 0 ) { fileloader->AddWaveFilesToThread( list ); }
// Con_Printf( "CWaveBrowser: selected %i sounds\n", loadcount );
}
void CWaveBrowser::RepopulateTree() { PopulateTree( m_pFileTree->GetSelectedPath() ); }
void CWaveBrowser::BuildSelectionList( CUtlVector< CWaveFile * >& selected ) { selected.RemoveAll();
int idx = -1; do { idx = m_pListView->getNextSelectedItem( idx ); if ( idx != -1 ) { CWaveFile *wav = (CWaveFile *)m_pListView->getUserData( idx, 0 ); if ( wav ) { selected.AddToTail( wav ); } } } while ( idx != -1 ); }
void CWaveBrowser::ShowContextMenu( void ) { SetActiveTool( this );
BuildSelectionList( m_CurrentSelection ); if ( m_CurrentSelection.Count() <= 0 ) return;
POINT pt; GetCursorPos( &pt ); ScreenToClient( (HWND)getHandle(), &pt );
// New scene, edit comments
mxPopupMenu *pop = new mxPopupMenu();
if ( m_CurrentSelection.Count() == 1 ) { pop->add ("&Play", IDC_SB_PLAY ); // pop->addSeparator();
}
// pop->add( "Import Sentence Data", IDC_SB_IMPORTSENTENCE );
// pop->add( "Export Sentence Data", IDC_SB_EXPORTSENTENCE );
pop->popup( this, pt.x, pt.y ); }
void CWaveBrowser::OnPlay() { SetActiveTool( this );
BuildSelectionList( m_CurrentSelection ); if ( m_CurrentSelection.Count() == 1 ) { CWaveFile *wav = m_CurrentSelection[ 0 ]; if ( wav ) { wav->Play(); } } }
static void SplitFileName( char const *in, char *path, int maxpath, char *filename, int maxfilename ) { char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT];
_splitpath( in, drive, dir, fname, ext );
if ( dir[0] ) { Q_snprintf( path, maxpath, "\\%s", dir ); } else { path[0] = 0; } Q_snprintf( filename, maxfilename, "%s%s", fname, ext ); }
//-----------------------------------------------------------------------------
// Purpose:
// Input : *se -
//-----------------------------------------------------------------------------
void CWaveBrowser::JumpToItem( CWaveFile *wav ) {
SetActiveTool( this );
char path[ 256 ]; char filename[ 256 ];
SplitFileName( wav->GetFileName(), path, sizeof( path ), filename, sizeof( filename ) );
char *usepath = path + Q_strlen( "/sound/" ); PopulateTree( usepath );
int idx = 0; int c = m_pListView->getItemCount(); for ( ; idx < c; idx++ ) { CWaveFile *item = (CWaveFile *)m_pListView->getUserData( idx, 0 ); if ( !Q_stricmp( item->GetFileName(), wav->GetFileName() ) ) { break; } }
if ( idx < c ) { m_pListView->scrollToItem( idx ); } }
CWaveFile *CWaveBrowser::FindEntry( char const *wavname, bool jump /*= false*/ ) { int idx = m_AllSounds.Find( wavname ); if ( idx != m_AllSounds.InvalidIndex() ) { CWaveFile *wav = m_AllSounds[ idx ]; if ( jump ) { JumpToItem( wav ); }
return wav; }
return NULL; }
int CWaveBrowser::GetSoundCount() const { return m_AllSounds.Count(); }
CWaveFile *CWaveBrowser::GetSound( int index ) { if ( index < 0 || index >= (int)m_AllSounds.Count() ) return NULL;
return m_AllSounds[ index ]; }
void CWaveBrowser::OnSearch() { SetActiveTool( this );
m_bTextSearch = true;
PopulateTree( GetSearchString()); }
void CWaveBrowser::OnCancelSearch() { SetActiveTool( this );
m_bTextSearch = false;
PopulateTree( m_pFileTree->GetSelectedPath() ); }
char const *CWaveBrowser::GetSearchString() { return m_pOptions->GetSearchString(); }
void CWaveBrowser::Think( float dt ) { int pending = fileloader->GetPendingLoadCount(); if ( pending != m_nPrevProcessed ) { m_nPrevProcessed = pending;
// Put into suffix of window title
if ( pending == 0 ) { SetSuffix( "" ); } else { SetSuffix( va( " - %i", pending ) ); } }
int c = fileloader->ProcessCompleted(); if ( c > 0 ) { RepopulateTree(); } }
void CWaveBrowser::SetEvent( CChoreoEvent *event ) { if ( event->GetType() != CChoreoEvent::SPEAK ) return;
SetCurrent( FacePoser_TranslateSoundName( event->GetParameters() ) ); }
void CWaveBrowser::SetCurrent( char const *filename ) { // Get sound name and look up .wav from it
char const *p = filename; if ( p && ( !Q_strnicmp( p, "sound/", 6 ) || !Q_strnicmp( p, "sound\\", 6 ) ) ) { p += 6; }
char fn[ 512 ]; Q_strncpy( fn, p, sizeof( fn ) ); Q_FixSlashes( fn );
int i; int c = m_pListView->getItemCount();
for ( i = 0; i < c; ++i ) { CWaveFile *wav = reinterpret_cast< CWaveFile * >( m_pListView->getUserData( i, COL_WAV ) ); if ( !wav ) continue;
char fixed[ 512 ]; Q_strncpy( fixed, wav->GetName(), sizeof( fixed ) ); Q_FixSlashes( fixed );
if ( !Q_stricmp( fixed, fn ) ) { m_pListView->scrollToItem( i ); m_pListView->setSelected( i, true ); } else { m_pListView->setSelected( i, false ); } } }
|