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.
200 lines
4.7 KiB
200 lines
4.7 KiB
//========= 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 ); |
|
}
|
|
|