diff options
Diffstat (limited to 'hammer/ScenePreviewDlg.cpp')
| -rw-r--r-- | hammer/ScenePreviewDlg.cpp | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/hammer/ScenePreviewDlg.cpp b/hammer/ScenePreviewDlg.cpp new file mode 100644 index 0000000..16687ed --- /dev/null +++ b/hammer/ScenePreviewDlg.cpp @@ -0,0 +1,200 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "stdafx.h" +#include "hammer.h" +#include "ScenePreviewDlg.h" +#include "choreoscene.h" +#include "soundsystem.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> + + +#define WM_SCENEPREVIEW_IDLE (WM_USER+1) + + +BEGIN_MESSAGE_MAP(CScenePreviewDlg, CDialog) + //{{AFX_MSG_MAP(CScenePreviewDlg) + ON_BN_CLICKED(IDCANCEL, OnCancel) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +CScenePreviewDlg::CScenePreviewDlg( CChoreoScene *pScene, const char *pFilename, CWnd* pParent /*=NULL*/ ) + : CDialog(CScenePreviewDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CScenePreviewDlg) + m_pScene = pScene; + m_iLastEventPlayed = -2; // Don't do anything yet. + m_hExitThreadEvent = NULL; + m_hIdleEventHandledEvent = NULL; + m_hIdleThread = NULL; + V_strncpy( m_SceneFilename, pFilename, sizeof( m_SceneFilename ) ); +} + + +CScenePreviewDlg::~CScenePreviewDlg() +{ + EndThread(); + delete m_pScene; +} + + +void CScenePreviewDlg::EndThread() +{ + if ( m_hIdleThread ) + { + SetEvent( m_hExitThreadEvent ); + WaitForSingleObject( m_hIdleThread, INFINITE ); + CloseHandle( m_hIdleThread ); + CloseHandle( m_hExitThreadEvent ); + CloseHandle( m_hIdleEventHandledEvent ); + m_hIdleThread = m_hExitThreadEvent = m_hIdleEventHandledEvent = NULL; + } +} + + +BOOL CScenePreviewDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + // Setup the control showing the scene name. + CString str; + GetDlgItemText( IDC_SCENE_NAME, str ); + str = str + " " + m_SceneFilename; + SetDlgItemText( IDC_SCENE_NAME, str ); + + CString strNone; + strNone.LoadString( IDS_NONE ); + SetDlgItemText( IDC_CURRENT_SOUND, strNone ); + SetDlgItemText( IDC_NEXT_SOUND, strNone ); + + m_iLastEventPlayed = -1; + m_flStartTime = Plat_FloatTime(); + + // Start on the first event.. + for ( int i = 0; i < m_pScene->GetNumEvents(); i++ ) + { + CChoreoEvent *e = m_pScene->GetEvent( i ); + if ( e && e->GetType() == CChoreoEvent::SPEAK ) + { + m_flStartTime -= e->GetStartTime(); + break; + } + } + + // Create our idle thread. + m_hExitThreadEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); + m_hIdleEventHandledEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); + m_hIdleThread = CreateThread( NULL, 0, &CScenePreviewDlg::StaticIdleThread, this, 0, NULL ); + + return TRUE; +} + + +DWORD CScenePreviewDlg::StaticIdleThread( LPVOID pParameter ) +{ + return ((CScenePreviewDlg*)pParameter)->IdleThread(); +} + +DWORD CScenePreviewDlg::IdleThread() +{ + HANDLE handles[2] = {m_hExitThreadEvent, m_hIdleEventHandledEvent}; + + while ( 1 ) + { + // Send the event to the window. + PostMessage( WM_SCENEPREVIEW_IDLE, 0, 0 ); + + DWORD ret = WaitForMultipleObjects( ARRAYSIZE( handles ), handles, false, INFINITE ); + if ( ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT ) + return 0; + + Sleep( 100 ); // Only handle idle 10x/sec. + } +} + + +void CScenePreviewDlg::OnIdle() +{ + double flElapsed = Plat_FloatTime() - m_flStartTime; + + // Find the next sound to play. + int iLastSound = -1; + for ( int i = 0; i < m_pScene->GetNumEvents(); i++ ) + { + CChoreoEvent *e = m_pScene->GetEvent( i ); + if ( !e || e->GetType() != CChoreoEvent::SPEAK ) + continue; + + if ( flElapsed > e->GetStartTime() ) + iLastSound = i; + } + + // Is there another sound to play in here? + if ( iLastSound >= 0 && iLastSound != m_iLastEventPlayed ) + { + m_iLastEventPlayed = iLastSound; + + // Play the current sound. + CChoreoEvent *pChoreoEvent = m_pScene->GetEvent( iLastSound ); + const char *pSoundName = pChoreoEvent->GetParameters(); + + SoundType_t soundType; + int nIndex; + if ( g_Sounds.FindSoundByName( pSoundName, &soundType, &nIndex ) ) + { + bool bRet = g_Sounds.Play( soundType, nIndex ); + + CString curSound = pSoundName; + if ( !bRet ) + { + CString strErrorPlaying; + strErrorPlaying.LoadString( IDS_ERROR_PLAYING ); + curSound += " " + strErrorPlaying; + } + SetDlgItemText( IDC_CURRENT_SOUND, curSound ); + } + + // Find the next sound event. + CString str; + str.LoadString( IDS_NONE ); + for ( int i=iLastSound+1; i < m_pScene->GetNumEvents(); i++ ) + { + CChoreoEvent *e = m_pScene->GetEvent( i ); + if ( e && e->GetType() == CChoreoEvent::SPEAK ) + { + str = e->GetParameters(); + break; + } + } + SetDlgItemText( IDC_NEXT_SOUND, str ); + } +} + + +LRESULT CScenePreviewDlg::DefWindowProc( UINT message, WPARAM wParam, LPARAM lParam ) +{ + // We handle the enter key specifically because the default combo box behavior is to + // reset the text and all this stuff we don't want. + if ( message == WM_SCENEPREVIEW_IDLE ) + { + OnIdle(); + SetEvent( m_hIdleEventHandledEvent ); + return 0; + } + + return CDialog::DefWindowProc( message, wParam, lParam ); +} + + +void CScenePreviewDlg::OnCancel(void) +{ + g_Sounds.StopSound(); + EndThread(); + EndDialog( 0 ); +} |