mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -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 );
|
||||
}
|
||||
Reference in New Issue
Block a user