1
@@ -0,0 +1,127 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef AUDIOWAVEOUTPUT_H
|
||||
#define AUDIOWAVEOUTPUT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "sound.h"
|
||||
#include "utlvector.h"
|
||||
|
||||
#define OUTPUT_BUFFER_COUNT 32
|
||||
#define MAX_CHANNELS 16
|
||||
|
||||
class CAudioMixer;
|
||||
|
||||
class CAudioMixerState
|
||||
{
|
||||
public:
|
||||
CAudioMixer *mixer;
|
||||
int submit_mixer_sample;
|
||||
};
|
||||
|
||||
class CAudioBuffer
|
||||
{
|
||||
public:
|
||||
WAVEHDR *hdr;
|
||||
bool submitted;
|
||||
int submit_sample_count;
|
||||
|
||||
CUtlVector< CAudioMixerState > m_Referenced;
|
||||
};
|
||||
|
||||
#define OUTPUT_SAMPLE_RATE 44100
|
||||
#define PAINTBUFFER_SIZE 1024
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int left;
|
||||
int right;
|
||||
} portable_samplepair_t;
|
||||
|
||||
class CAudioDeviceSWMix : public IAudioDevice
|
||||
{
|
||||
public:
|
||||
virtual void Mix8Mono( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward = true );
|
||||
virtual void Mix8Stereo( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward = true );
|
||||
virtual void Mix16Mono( channel_t *pChannel, short *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward = true );
|
||||
virtual void Mix16Stereo( channel_t *pChannel, short *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward = true );
|
||||
virtual int MaxSampleCount( void );
|
||||
virtual void MixBegin( void );
|
||||
|
||||
void TransferBufferStereo16( short *pOutput, int sampleCount );
|
||||
|
||||
private:
|
||||
portable_samplepair_t m_paintbuffer[ PAINTBUFFER_SIZE ];
|
||||
};
|
||||
|
||||
class CAudioWaveOutput : public CAudioOutput
|
||||
{
|
||||
public:
|
||||
CAudioWaveOutput( void );
|
||||
~CAudioWaveOutput( void );
|
||||
|
||||
// returns the size of each sample in bytes
|
||||
virtual int SampleSize( void ) { return 2; }
|
||||
|
||||
// returns the sampling rate of the data
|
||||
virtual int SampleRate( void ) { return OUTPUT_SAMPLE_RATE; }
|
||||
|
||||
// returns the mono/stereo status of this device (true if stereo)
|
||||
virtual bool IsStereo( void ) { return true; }
|
||||
|
||||
// mix a buffer up to time (time is absolute)
|
||||
virtual void Update( float time );
|
||||
|
||||
virtual void Flush( void );
|
||||
|
||||
virtual void AddSource( CAudioMixer *pSource );
|
||||
virtual void StopSounds( void );
|
||||
virtual int FindSourceIndex( CAudioMixer *pSource );
|
||||
|
||||
virtual int GetOutputPosition( void );
|
||||
virtual float GetAmountofTimeAhead( void );
|
||||
virtual int GetNumberofSamplesAhead( void );
|
||||
|
||||
virtual CAudioMixer *GetMixerForSource( CAudioSource *pSource );
|
||||
|
||||
|
||||
private:
|
||||
void OpenDevice( void );
|
||||
bool ValidDevice( void ) { return m_deviceHandle != 0; }
|
||||
void ClearDevice( void ) { m_deviceHandle = NULL; }
|
||||
CAudioBuffer *GetEmptyBuffer( void );
|
||||
void SilenceBuffer( short *pSamples, int sampleCount );
|
||||
|
||||
void SetChannel( int channelIndex, CAudioMixer *pSource );
|
||||
void FreeChannel( int channelIndex );
|
||||
|
||||
void RemoveMixerChannelReferences( CAudioMixer *mixer );
|
||||
void AddToReferencedList( CAudioMixer *mixer, CAudioBuffer *buffer );
|
||||
void RemoveFromReferencedList( CAudioMixer *mixer, CAudioBuffer *buffer );
|
||||
bool IsSourceReferencedByActiveBuffer( CAudioMixer *mixer );
|
||||
bool IsSoundInReferencedList( CAudioMixer *mixer, CAudioBuffer *buffer );
|
||||
|
||||
// Compute how many samples we've mixed since most recent buffer submission
|
||||
void ComputeSampleAheadAmount( void );
|
||||
|
||||
HWAVEOUT m_deviceHandle;
|
||||
|
||||
float m_mixTime;
|
||||
float m_baseTime;
|
||||
int m_sampleIndex;
|
||||
CAudioBuffer m_buffers[ OUTPUT_BUFFER_COUNT ];
|
||||
|
||||
CAudioMixer *m_sourceList[MAX_CHANNELS];
|
||||
int m_nEstimatedSamplesAhead;
|
||||
public:
|
||||
CAudioDeviceSWMix m_audioDevice;
|
||||
|
||||
};
|
||||
#endif // AUDIOWAVEOUTPUT_H
|
||||
@@ -0,0 +1,65 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include <mxtk/mx.h>
|
||||
#include "tier0/dbg.h"
|
||||
#include "basedialogparams.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : self -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseDialogParams::PositionSelf( void *self )
|
||||
{
|
||||
RECT rcDlg;
|
||||
HWND dlgWindow = (HWND)self;
|
||||
GetWindowRect( dlgWindow, &rcDlg );
|
||||
|
||||
// Get relative to primary monitor instead of actual window parent
|
||||
RECT rcParent;
|
||||
rcParent.left = 0;
|
||||
rcParent.right = rcParent.left + GetSystemMetrics( SM_CXFULLSCREEN );
|
||||
rcParent.top = 0;
|
||||
rcParent.bottom = rcParent.top + GetSystemMetrics( SM_CYFULLSCREEN );
|
||||
|
||||
int dialogw, dialogh;
|
||||
int parentw, parenth;
|
||||
|
||||
parentw = rcParent.right - rcParent.left;
|
||||
parenth = rcParent.bottom - rcParent.top;
|
||||
dialogw = rcDlg.right - rcDlg.left;
|
||||
dialogh = rcDlg.bottom - rcDlg.top;
|
||||
|
||||
int dlgleft, dlgtop;
|
||||
dlgleft = ( parentw - dialogw ) / 2;
|
||||
dlgtop = ( parenth - dialogh ) / 2;
|
||||
|
||||
if ( m_bPositionDialog )
|
||||
{
|
||||
int top = m_nTop - dialogh - 5;
|
||||
int left = m_nLeft;
|
||||
|
||||
MoveWindow( dlgWindow,
|
||||
left,
|
||||
top,
|
||||
dialogw,
|
||||
dialogh,
|
||||
TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
MoveWindow( dlgWindow,
|
||||
dlgleft,
|
||||
dlgtop,
|
||||
dialogw,
|
||||
dialogh,
|
||||
TRUE
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef BASEDIALOGPARAMS_H
|
||||
#define BASEDIALOGPARAMS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
struct CBaseDialogParams
|
||||
{
|
||||
// i dialog title
|
||||
char m_szDialogTitle[ 128 ];
|
||||
|
||||
bool m_bPositionDialog;
|
||||
int m_nLeft;
|
||||
int m_nTop;
|
||||
|
||||
void PositionSelf( void * self );
|
||||
};
|
||||
|
||||
#endif // BASEDIALOGPARAMS_H
|
||||
@@ -0,0 +1,15 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// scenemanager.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
@@ -0,0 +1,28 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef CBASE_H
|
||||
#define CBASE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// cbase.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
#include "mxtk/mx.h"
|
||||
#include "mxtk/mxwindow.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "utlvector.h"
|
||||
#include "vstdlib/random.h"
|
||||
#include "sharedInterface.h"
|
||||
#include "scenemanager_tools.h"
|
||||
#include "tier3/tier3.h"
|
||||
|
||||
#endif // CBASE_H
|
||||
@@ -0,0 +1,107 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include <mxtk/mx.h>
|
||||
#include "utlvector.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Helper class that automagically sets up and destroys a memory device-
|
||||
// context for flicker-free refershes
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDrawHelper
|
||||
{
|
||||
public:
|
||||
// Construction/destruction
|
||||
CDrawHelper( mxWindow *widget);
|
||||
CDrawHelper( mxWindow *widget, COLORREF bgColor );
|
||||
CDrawHelper( mxWindow *widget, int x, int y, int w, int h, COLORREF bgColor );
|
||||
CDrawHelper( mxWindow *widget, RECT& bounds );
|
||||
CDrawHelper( mxWindow *widget, RECT& bounds, COLORREF bgColor );
|
||||
virtual ~CDrawHelper( void );
|
||||
|
||||
// Allow caller to draw onto the memory dc, too
|
||||
HDC GrabDC( void );
|
||||
|
||||
// Compute text size
|
||||
static int CalcTextWidth( const char *font, int pointsize, int weight, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
static int CalcTextWidth( HFONT font, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
|
||||
int CalcTextWidthW( const char *font, int pointsize, int weight, PRINTF_FORMAT_STRING const wchar_t *fmt, ... );
|
||||
int CalcTextWidthW( HFONT font, PRINTF_FORMAT_STRING const wchar_t *fmt, ... );
|
||||
void DrawColoredTextW( const char *font, int pointsize, int weight, COLORREF clr, RECT& rcText, PRINTF_FORMAT_STRING const wchar_t *fmt, ... );
|
||||
void DrawColoredTextW( HFONT font, COLORREF clr, RECT& rcText, PRINTF_FORMAT_STRING const wchar_t *fmt, ... );
|
||||
void DrawColoredTextCharsetW( const char *font, int pointsize, int weight, DWORD charset, COLORREF clr, RECT& rcText, PRINTF_FORMAT_STRING const wchar_t *fmt, ... );
|
||||
|
||||
void CalcTextRect( const char *font, int pointsize, int weight, int maxwidth, RECT& rcText, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
|
||||
// Draw text
|
||||
void DrawColoredText( const char *font, int pointsize, int weight, COLORREF clr, RECT& rcText, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
void DrawColoredText( HFONT font, COLORREF clr, RECT& rcText, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
void DrawColoredTextCharset( const char *font, int pointsize, int weight, DWORD charset, COLORREF clr, RECT& rcText, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
void DrawColoredTextMultiline( const char *font, int pointsize, int weight, COLORREF clr, RECT& rcText, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
// Draw a line
|
||||
void DrawColoredLine( COLORREF clr, int style, int width, int x1, int y1, int x2, int y2 );
|
||||
void DrawColoredPolyLine( COLORREF clr, int style, int width, CUtlVector< POINT >& points );
|
||||
|
||||
// Draw a blending ramp
|
||||
POINTL DrawColoredRamp( COLORREF clr, int style, int width, int x1, int y1, int x2, int y2, float rate, float sustain );
|
||||
// Draw a filled rect
|
||||
void DrawFilledRect( COLORREF clr, int x1, int y1, int x2, int y2 );
|
||||
// Draw an outlined rect
|
||||
void DrawOutlinedRect( COLORREF clr, int style, int width, int x1, int y1, int x2, int y2 );
|
||||
void DrawOutlinedRect( COLORREF clr, int style, int width, RECT& rc );
|
||||
|
||||
void DrawFilledRect( HBRUSH br, RECT& rc );
|
||||
void DrawFilledRect( COLORREF clr, RECT& rc );
|
||||
|
||||
void DrawGradientFilledRect( RECT& rc, COLORREF clr1, COLORREF clr2, bool vertical );
|
||||
|
||||
void DrawLine( int x1, int y1, int x2, int y2, COLORREF clr, int thickness );
|
||||
|
||||
// Draw a triangle
|
||||
void DrawTriangleMarker( RECT& rc, COLORREF fill, bool inverted = false );
|
||||
|
||||
void DrawCircle( COLORREF clr, int x, int y, int radius, bool filled = true );
|
||||
|
||||
// Get width/height of draw area
|
||||
int GetWidth( void );
|
||||
int GetHeight( void );
|
||||
|
||||
// Get client rect for drawing
|
||||
void GetClientRect( RECT& rc );
|
||||
|
||||
void StartClipping( RECT& clipRect );
|
||||
void StopClipping( void );
|
||||
|
||||
// Remap rect if we're using a clipped viewport
|
||||
void OffsetSubRect( RECT& rc );
|
||||
|
||||
private:
|
||||
// Internal initializer
|
||||
void Init( mxWindow *widget, int x, int y, int w, int h, COLORREF bgColor);
|
||||
|
||||
void ClipToRects( void );
|
||||
|
||||
// The window we are drawing on
|
||||
HWND m_hWnd;
|
||||
// The final DC
|
||||
HDC m_dcReal;
|
||||
// The working DC
|
||||
HDC m_dcMemory;
|
||||
// Client area and offsets
|
||||
RECT m_rcClient;
|
||||
int m_x, m_y;
|
||||
int m_w, m_h;
|
||||
// Bitmap for drawing in the memory DC
|
||||
HBITMAP m_bmMemory;
|
||||
HBITMAP m_bmOld;
|
||||
// Remember the original default color
|
||||
COLORREF m_clrOld;
|
||||
|
||||
CUtlVector < RECT > m_ClipRects;
|
||||
HRGN m_ClipRegion;
|
||||
};
|
||||
@@ -0,0 +1,369 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "sentence.h"
|
||||
#include "wavefile.h"
|
||||
#include "tier2/riff.h"
|
||||
#include "filesystem.h"
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include "IFileLoader.h"
|
||||
|
||||
bool SceneManager_LoadSentenceFromWavFileUsingIO( char const *wavfile, CSentence& sentence, IFileReadBinary& io );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Implements the RIFF i/o interface on stdio
|
||||
//-----------------------------------------------------------------------------
|
||||
class ThreadIOReadBinary : public IFileReadBinary
|
||||
{
|
||||
public:
|
||||
int open( const char *pFileName )
|
||||
{
|
||||
char filename[ 512 ];
|
||||
Q_snprintf( filename, sizeof( filename ), "%s%s", SceneManager_GetGameDirectory(), pFileName );
|
||||
return (int)_open( filename, _O_BINARY | _O_RDONLY );
|
||||
}
|
||||
|
||||
int read( void *pOutput, int size, int file )
|
||||
{
|
||||
if ( file == -1 )
|
||||
return 0;
|
||||
|
||||
return _read( file, pOutput, size );
|
||||
}
|
||||
|
||||
void seek( int file, int pos )
|
||||
{
|
||||
if ( file == -1 )
|
||||
return;
|
||||
|
||||
_lseek( file, pos, SEEK_SET );
|
||||
}
|
||||
|
||||
unsigned int tell( int file )
|
||||
{
|
||||
if ( file == -1 )
|
||||
return 0;
|
||||
|
||||
return _tell( file );
|
||||
}
|
||||
|
||||
unsigned int size( int file )
|
||||
{
|
||||
if ( file == -1 )
|
||||
return 0;
|
||||
|
||||
long curpos = tell( file );
|
||||
_lseek( file, 0, SEEK_END );
|
||||
int s = tell( file );
|
||||
_lseek( file, curpos, SEEK_SET );
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void close( int file )
|
||||
{
|
||||
if ( file == -1 )
|
||||
return;
|
||||
|
||||
_close( file );
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: All wavefile I/O occurs on a thread
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFileLoaderThread : public IFileLoader
|
||||
{
|
||||
public:
|
||||
struct SentenceRequest
|
||||
{
|
||||
SentenceRequest()
|
||||
{
|
||||
filename[ 0 ] = 0;
|
||||
sentence.Reset();
|
||||
wavefile = NULL;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
bool valid;
|
||||
char filename[ 256 ];
|
||||
CSentence sentence;
|
||||
|
||||
CWaveFile *wavefile;
|
||||
};
|
||||
|
||||
// Construction
|
||||
CFileLoaderThread( void );
|
||||
virtual ~CFileLoaderThread( void );
|
||||
|
||||
// Sockets add/remove themselves via their constructor
|
||||
virtual void AddWaveFilesToThread( CUtlVector< CWaveFile * >& wavefiles );
|
||||
|
||||
// Lock changes to wavefile list, etc.
|
||||
virtual void Lock( void );
|
||||
// Unlock wavefile list, etc.
|
||||
virtual void Unlock( void );
|
||||
|
||||
// Retrieve handle to shutdown event
|
||||
virtual HANDLE GetShutdownHandle( void );
|
||||
|
||||
// Caller should call lock before accessing any of these methods and unlock afterwards!!!
|
||||
virtual int ProcessCompleted();
|
||||
|
||||
int DoThreadWork();
|
||||
|
||||
virtual void Start();
|
||||
|
||||
private:
|
||||
// Critical section used for synchronizing access to wavefile list
|
||||
CRITICAL_SECTION cs;
|
||||
// List of wavefiles we are listening on
|
||||
CUtlVector< SentenceRequest * > m_FileList;
|
||||
|
||||
CUtlVector< SentenceRequest * > m_Pending;
|
||||
CUtlVector< SentenceRequest * > m_Completed;
|
||||
// Thread handle
|
||||
HANDLE m_hThread;
|
||||
// Thread id
|
||||
DWORD m_nThreadId;
|
||||
// Event to set when we want to tell the thread to shut itself down
|
||||
HANDLE m_hShutdown;
|
||||
|
||||
ThreadIOReadBinary m_ThreadIO;
|
||||
bool m_bLocked;
|
||||
|
||||
int m_nTotalAdds;
|
||||
int m_nTotalPending;
|
||||
int m_nTotalProcessed;
|
||||
int m_nTotalCompleted;
|
||||
};
|
||||
|
||||
// Singleton handler
|
||||
static CFileLoaderThread g_WaveLoader;
|
||||
extern IFileLoader *fileloader = &g_WaveLoader;
|
||||
|
||||
int CFileLoaderThread::DoThreadWork()
|
||||
{
|
||||
int i;
|
||||
// Check for shutdown event
|
||||
if ( WAIT_OBJECT_0 == WaitForSingleObject( GetShutdownHandle(), 0 ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// No changes to list right now
|
||||
Lock();
|
||||
// Move new items to work list
|
||||
int newItems = m_FileList.Count();
|
||||
for ( i = 0; i < newItems; i++ )
|
||||
{
|
||||
// Move to pending and issue async i/o calls
|
||||
m_Pending.AddToTail( m_FileList[ i ] );
|
||||
|
||||
m_nTotalPending++;
|
||||
}
|
||||
m_FileList.RemoveAll();
|
||||
// Done adding new work items
|
||||
Unlock();
|
||||
|
||||
int remaining = m_Pending.Count();
|
||||
if ( !remaining )
|
||||
return 1;
|
||||
|
||||
int workitems = remaining; // min( remaining, 1000 );
|
||||
|
||||
CUtlVector< SentenceRequest * > transfer;
|
||||
|
||||
for ( i = 0; i < workitems; i++ )
|
||||
{
|
||||
SentenceRequest *r = m_Pending[ 0 ];
|
||||
m_Pending.Remove( 0 );
|
||||
|
||||
transfer.AddToTail( r );
|
||||
// Do the work
|
||||
|
||||
m_nTotalProcessed++;
|
||||
|
||||
r->valid = SceneManager_LoadSentenceFromWavFileUsingIO( r->filename, r->sentence, m_ThreadIO );
|
||||
}
|
||||
|
||||
// Now move to completed list
|
||||
Lock();
|
||||
for ( i = 0; i < workitems; i++ )
|
||||
{
|
||||
SentenceRequest *r = transfer[ i ];
|
||||
if ( r->valid )
|
||||
{
|
||||
m_nTotalCompleted++;
|
||||
|
||||
m_Completed.AddToTail( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
delete r;
|
||||
}
|
||||
}
|
||||
Unlock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CFileLoaderThread::ProcessCompleted()
|
||||
{
|
||||
Lock();
|
||||
int c = m_Completed.Count();
|
||||
for ( int i = c - 1; i >= 0 ; i-- )
|
||||
{
|
||||
SentenceRequest *r = m_Completed[ i ];
|
||||
|
||||
r->wavefile->SetThreadLoadedSentence( r->sentence );
|
||||
|
||||
delete r;
|
||||
}
|
||||
m_Completed.RemoveAll();
|
||||
Unlock();
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Main winsock processing thread
|
||||
// Input : threadobject -
|
||||
// Output : static DWORD WINAPI
|
||||
//-----------------------------------------------------------------------------
|
||||
static DWORD WINAPI FileLoaderThreadFunc( LPVOID threadobject )
|
||||
{
|
||||
// Get pointer to CFileLoaderThread object
|
||||
CFileLoaderThread *wavefilethread = ( CFileLoaderThread * )threadobject;
|
||||
Assert( wavefilethread );
|
||||
if ( !wavefilethread )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Keep looking for data until shutdown event is triggered
|
||||
while ( 1 )
|
||||
{
|
||||
if( !wavefilethread->DoThreadWork() )
|
||||
break;
|
||||
|
||||
// Yield a small bit of time to main app
|
||||
Sleep( 100 );
|
||||
}
|
||||
|
||||
ExitThread( 0 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Construction
|
||||
//-----------------------------------------------------------------------------
|
||||
CFileLoaderThread::CFileLoaderThread( void )
|
||||
{
|
||||
m_nTotalAdds = 0;
|
||||
m_nTotalProcessed = 0;
|
||||
m_nTotalCompleted = 0;
|
||||
m_nTotalPending = 0;
|
||||
|
||||
m_bLocked = false;
|
||||
|
||||
InitializeCriticalSection( &cs );
|
||||
|
||||
m_hShutdown = CreateEvent( NULL, TRUE, FALSE, NULL );
|
||||
Assert( m_hShutdown );
|
||||
|
||||
m_hThread = NULL;
|
||||
Start();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFileLoaderThread::Start()
|
||||
{
|
||||
m_hThread = CreateThread( NULL, 0, FileLoaderThreadFunc, (void *)this, 0, &m_nThreadId );
|
||||
Assert( m_hThread );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CFileLoaderThread::~CFileLoaderThread( void )
|
||||
{
|
||||
Lock();
|
||||
{
|
||||
SetEvent( m_hShutdown );
|
||||
Sleep( 2 );
|
||||
TerminateThread( m_hThread, 0 );
|
||||
}
|
||||
Unlock();
|
||||
|
||||
// Kill the wavefile
|
||||
//!! need to validate this line
|
||||
// Assert( !m_FileList );
|
||||
|
||||
CloseHandle( m_hThread );
|
||||
|
||||
CloseHandle( m_hShutdown );
|
||||
|
||||
DeleteCriticalSection( &cs );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns handle of shutdown event
|
||||
// Output : HANDLE
|
||||
//-----------------------------------------------------------------------------
|
||||
HANDLE CFileLoaderThread::GetShutdownHandle( void )
|
||||
{
|
||||
return m_hShutdown;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Locks object and adds wavefile to thread
|
||||
// Input : *wavefile -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFileLoaderThread::AddWaveFilesToThread( CUtlVector< CWaveFile * >& wavefiles )
|
||||
{
|
||||
Lock();
|
||||
|
||||
int c = wavefiles.Count();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
SentenceRequest *request = new SentenceRequest;
|
||||
request->wavefile = wavefiles[ i ];
|
||||
Q_strncpy( request->filename, request->wavefile->GetFileName(), sizeof( request->filename ) );
|
||||
|
||||
|
||||
m_FileList.AddToTail( request );
|
||||
|
||||
m_nTotalAdds++;
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFileLoaderThread::Lock( void )
|
||||
{
|
||||
EnterCriticalSection( &cs );
|
||||
Assert( !m_bLocked );
|
||||
m_bLocked = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFileLoaderThread::Unlock( void )
|
||||
{
|
||||
Assert( m_bLocked );
|
||||
m_bLocked = false;
|
||||
LeaveCriticalSection( &cs );
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,29 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef IFILELOADER_H
|
||||
#define IFILELOADER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utlvector.h"
|
||||
|
||||
class CWaveFile;
|
||||
|
||||
class IFileLoader
|
||||
{
|
||||
public:
|
||||
virtual void AddWaveFilesToThread( CUtlVector< CWaveFile * >& wavefiles ) = 0;
|
||||
|
||||
virtual int ProcessCompleted() = 0;
|
||||
|
||||
virtual void Start() = 0;
|
||||
};
|
||||
|
||||
extern IFileLoader *fileloader;
|
||||
|
||||
#endif // IFILELOADER_H
|
||||
@@ -0,0 +1,79 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "resource.h"
|
||||
#include "InputProperties.h"
|
||||
#include "workspacemanager.h"
|
||||
|
||||
static CInputParams g_Params;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : hwndDlg -
|
||||
// uMsg -
|
||||
// wParam -
|
||||
// lParam -
|
||||
// Output : static BOOL CALLBACK
|
||||
//-----------------------------------------------------------------------------
|
||||
static BOOL CALLBACK InputPropertiesDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
// Insert code here to put the string (to find and replace with)
|
||||
// into the edit controls.
|
||||
// ...
|
||||
{
|
||||
g_Params.PositionSelf( hwndDlg );
|
||||
|
||||
SetDlgItemText( hwndDlg, IDC_INPUTSTRING, g_Params.m_szInputText );
|
||||
SetDlgItemText( hwndDlg, IDC_STATIC_PROMPT, g_Params.m_szPrompt );
|
||||
|
||||
SetWindowText( hwndDlg, g_Params.m_szDialogTitle );
|
||||
|
||||
SetFocus( GetDlgItem( hwndDlg, IDC_INPUTSTRING ) );
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_INPUTSTRING ), EM_SETSEL, 0, MAKELONG(0, 0xffff) );
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
g_Params.m_szInputText[ 0 ] = 0;
|
||||
GetDlgItemText( hwndDlg, IDC_INPUTSTRING, g_Params.m_szInputText, sizeof( g_Params.m_szInputText ) );
|
||||
EndDialog( hwndDlg, 1 );
|
||||
break;
|
||||
case IDCANCEL:
|
||||
EndDialog( hwndDlg, 0 );
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *view -
|
||||
// *actor -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int InputProperties( CInputParams *params )
|
||||
{
|
||||
g_Params = *params;
|
||||
|
||||
int retval = DialogBox( (HINSTANCE)GetModuleHandle( 0 ),
|
||||
MAKEINTRESOURCE( IDD_INPUTDIALOG ),
|
||||
(HWND)GetWorkspaceManager()->getHandle(),
|
||||
(DLGPROC)InputPropertiesDialogProc );
|
||||
|
||||
*params = g_Params;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef INPUTPROPERTIES_H
|
||||
#define INPUTPROPERTIES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basedialogparams.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CInputParams : public CBaseDialogParams
|
||||
{
|
||||
char m_szPrompt[ 256 ];
|
||||
|
||||
// i/o input text
|
||||
char m_szInputText[ 1024 ];
|
||||
};
|
||||
|
||||
// Display/create dialog
|
||||
int InputProperties( CInputParams *params );
|
||||
|
||||
#endif // INPUTPROPERTIES_H
|
||||
@@ -0,0 +1,45 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef ISCENEMANAGERSOUND_H
|
||||
#define ISCENEMANAGERSOUND_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CAudioSource;
|
||||
class CAudioMixer;
|
||||
class CAudioOuput;
|
||||
|
||||
class ISceneManagerSound
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void Init( void ) = 0;
|
||||
virtual void Shutdown( void ) = 0;
|
||||
virtual void Update( float time ) = 0;
|
||||
virtual void Flush( void ) = 0;
|
||||
|
||||
virtual CAudioSource *LoadSound( const char *wavfile ) = 0;
|
||||
|
||||
virtual void PlaySound( const char *wavfile, CAudioMixer **ppMixer ) = 0;
|
||||
|
||||
virtual void PlaySound( CAudioSource *source, CAudioMixer **ppMixer ) = 0;
|
||||
|
||||
virtual bool IsSoundPlaying( CAudioMixer *pMixer ) = 0;
|
||||
virtual CAudioMixer *FindMixer( CAudioSource *source ) = 0;
|
||||
|
||||
virtual void StopAll( void ) = 0;
|
||||
virtual void StopSound( CAudioMixer *mixer ) = 0;
|
||||
|
||||
virtual CAudioOuput *GetAudioOutput( void ) = 0;
|
||||
|
||||
virtual CAudioSource *FindOrAddSound( const char *filename ) = 0;
|
||||
};
|
||||
|
||||
extern ISceneManagerSound *sound;
|
||||
|
||||
#endif // ISCENEMANAGERSOUND_H
|
||||
@@ -0,0 +1,84 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "itreeitem.h"
|
||||
#include "mxtk/mxTreeView.h"
|
||||
#include "project.h"
|
||||
#include "scene.h"
|
||||
#include "soundentry.h"
|
||||
#include "vcdfile.h"
|
||||
#include "wavefile.h"
|
||||
#include "workspace.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *tree -
|
||||
// *parent -
|
||||
// Output : mxTreeViewItem
|
||||
//-----------------------------------------------------------------------------
|
||||
mxTreeViewItem *ITreeItem::FindItem( mxTreeView *tree, mxTreeViewItem *parent, bool recurse )
|
||||
{
|
||||
if ( !tree )
|
||||
return NULL;
|
||||
|
||||
mxTreeViewItem *child = tree->getFirstChild( parent );
|
||||
while ( child )
|
||||
{
|
||||
ITreeItem *treeItem = (ITreeItem *)tree->getUserData( child );
|
||||
if ( treeItem )
|
||||
{
|
||||
if ( treeItem == this )
|
||||
{
|
||||
return child;
|
||||
}
|
||||
|
||||
if ( recurse )
|
||||
{
|
||||
mxTreeViewItem *found = FindItem( tree, child, recurse );
|
||||
if ( found )
|
||||
{
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
child = tree->getNextChild( child );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ITreeItem *ITreeItem::GetParentItem()
|
||||
{
|
||||
if ( GetSoundEntry() )
|
||||
{
|
||||
return GetSoundEntry()->GetOwnerVCDFile();
|
||||
}
|
||||
|
||||
if ( GetVCDFile() )
|
||||
{
|
||||
return GetVCDFile()->GetOwnerScene();
|
||||
}
|
||||
|
||||
if ( GetScene() )
|
||||
{
|
||||
return GetScene()->GetOwnerProject();
|
||||
}
|
||||
|
||||
if ( GetProject() )
|
||||
{
|
||||
return GetProject()->GetOwnerWorkspace();
|
||||
}
|
||||
|
||||
if ( GetWaveFile() )
|
||||
{
|
||||
return GetWaveFile()->GetOwnerSoundEntry();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef ITREEITEM_H
|
||||
#define ITREEITEM_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CWorkspace;
|
||||
class CProject;
|
||||
class CScene;
|
||||
class CVCDFile;
|
||||
class CSoundEntry;
|
||||
class CWaveFile;
|
||||
class mxTreeView;
|
||||
|
||||
class ITreeItem
|
||||
{
|
||||
public:
|
||||
ITreeItem()
|
||||
{
|
||||
m_bExpanded = false;
|
||||
m_nOrdinal = -1;
|
||||
}
|
||||
|
||||
virtual char const *GetName() const = 0;
|
||||
|
||||
ITreeItem *GetParentItem();
|
||||
|
||||
virtual CWorkspace *GetWorkspace() = 0;
|
||||
virtual CProject *GetProject() = 0;
|
||||
virtual CScene *GetScene() = 0;
|
||||
virtual CVCDFile *GetVCDFile() = 0;
|
||||
virtual CSoundEntry *GetSoundEntry() = 0;
|
||||
virtual CWaveFile *GetWaveFile() = 0;
|
||||
|
||||
virtual int GetIconIndex() const = 0;
|
||||
|
||||
bool IsExpanded() const
|
||||
{
|
||||
return m_bExpanded;
|
||||
}
|
||||
|
||||
void SetExpanded( bool exp )
|
||||
{
|
||||
m_bExpanded = exp;
|
||||
}
|
||||
|
||||
mxTreeViewItem *FindItem( mxTreeView *tree, mxTreeViewItem *parent, bool recurse = false );
|
||||
|
||||
virtual void Checkout( bool updatestateicons = true ) = 0;
|
||||
virtual void Checkin( bool updatestateicons = true ) = 0;
|
||||
|
||||
virtual void MoveChildUp( ITreeItem *child ) = 0;
|
||||
virtual void MoveChildDown( ITreeItem *child ) = 0;
|
||||
|
||||
virtual bool IsFirstChild()
|
||||
{
|
||||
if ( !GetParentItem() )
|
||||
return false;
|
||||
|
||||
return GetParentItem()->IsChildFirst( this );
|
||||
}
|
||||
|
||||
virtual bool IsLastChild()
|
||||
{
|
||||
if ( !GetParentItem() )
|
||||
return false;
|
||||
|
||||
return GetParentItem()->IsChildLast( this );
|
||||
}
|
||||
|
||||
virtual bool IsChildFirst( ITreeItem *child ) = 0;
|
||||
virtual bool IsChildLast( ITreeItem *child ) = 0;
|
||||
|
||||
void SetOrdinal( int ordinal ) { m_nOrdinal = ordinal; }
|
||||
int GetOrdinal( void ) const { return m_nOrdinal; }
|
||||
|
||||
virtual void SetDirty( bool dirty ) = 0;
|
||||
private:
|
||||
bool m_bExpanded;
|
||||
int m_nOrdinal;
|
||||
};
|
||||
|
||||
#endif // ITREEITEM_H
|
||||
@@ -0,0 +1,138 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "resource.h"
|
||||
#include "MultipleRequest.h"
|
||||
#include "workspacemanager.h"
|
||||
|
||||
static CMultipleParams g_Params;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : hwndDlg -
|
||||
// uMsg -
|
||||
// wParam -
|
||||
// lParam -
|
||||
// Output : static BOOL CALLBACK
|
||||
//-----------------------------------------------------------------------------
|
||||
static BOOL CALLBACK MultipleRequestDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
// Insert code here to put the string (to find and replace with)
|
||||
// into the edit controls.
|
||||
// ...
|
||||
{
|
||||
g_Params.PositionSelf( hwndDlg );
|
||||
|
||||
SetDlgItemText( hwndDlg, IDC_PROMPT, g_Params.m_szPrompt );
|
||||
|
||||
SetWindowText( hwndDlg, g_Params.m_szDialogTitle );
|
||||
|
||||
SetFocus( GetDlgItem( hwndDlg, IDC_INPUTSTRING ) );
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_INPUTSTRING ), EM_SETSEL, 0, MAKELONG(0, 0xffff) );
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_YESALL:
|
||||
EndDialog( hwndDlg, CMultipleParams::YES_ALL );
|
||||
break;
|
||||
case IDC_YES:
|
||||
EndDialog( hwndDlg, CMultipleParams::YES );
|
||||
break;
|
||||
case IDC_NOSINGLE:
|
||||
EndDialog( hwndDlg, CMultipleParams::NO );
|
||||
break;
|
||||
case IDC_NOALL:
|
||||
EndDialog( hwndDlg, CMultipleParams::NO_ALL );
|
||||
break;
|
||||
//case IDCANCEL:
|
||||
// EndDialog( hwndDlg, CMultipleParams::CANCEL );
|
||||
// break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int g_MRContext = 1;
|
||||
static int g_MRCurrentContext;
|
||||
static int g_MRLastResult = -1;
|
||||
|
||||
void MultipleRequestChangeContext()
|
||||
{
|
||||
++g_MRContext;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *view -
|
||||
// *actor -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int _MultipleRequest( CMultipleParams *params )
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
if ( g_MRCurrentContext == g_MRContext &&
|
||||
g_MRLastResult != -1 )
|
||||
{
|
||||
if ( g_MRLastResult == CMultipleParams::YES_ALL )
|
||||
{
|
||||
retval = 0;
|
||||
}
|
||||
if ( g_MRLastResult == CMultipleParams::NO_ALL )
|
||||
{
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( retval == -1 )
|
||||
{
|
||||
g_Params = *params;
|
||||
|
||||
retval = DialogBox( (HINSTANCE)GetModuleHandle( 0 ),
|
||||
MAKEINTRESOURCE( IDD_MULTIPLEQUESTION ),
|
||||
(HWND)GetWorkspaceManager()->getHandle(),
|
||||
(DLGPROC)MultipleRequestDialogProc );
|
||||
|
||||
*params = g_Params;
|
||||
}
|
||||
|
||||
g_MRCurrentContext = g_MRContext;
|
||||
g_MRLastResult = retval;
|
||||
switch ( retval )
|
||||
{
|
||||
case CMultipleParams::YES_ALL:
|
||||
case CMultipleParams::YES:
|
||||
return 0;
|
||||
case CMultipleParams::NO_ALL:
|
||||
case CMultipleParams::NO:
|
||||
return 1;
|
||||
default:
|
||||
case CMultipleParams::CANCEL:
|
||||
return 2;
|
||||
}
|
||||
|
||||
Assert( 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
int MultipleRequest( char const *prompt )
|
||||
{
|
||||
CMultipleParams params;
|
||||
memset( ¶ms, 0, sizeof( params ) );
|
||||
Q_strcpy( params.m_szDialogTitle, g_appTitle );
|
||||
Q_strncpy( params.m_szPrompt, prompt, sizeof( params.m_szPrompt ) );
|
||||
|
||||
return _MultipleRequest( ¶ms );
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MULTIPLEREQUEST_H
|
||||
#define MULTIPLEREQUEST_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basedialogparams.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CMultipleParams : public CBaseDialogParams
|
||||
{
|
||||
enum
|
||||
{
|
||||
YES_ALL = 0,
|
||||
YES,
|
||||
NO,
|
||||
NO_ALL,
|
||||
CANCEL,
|
||||
};
|
||||
|
||||
char m_szPrompt[ 256 ];
|
||||
};
|
||||
|
||||
// Display/create dialog
|
||||
int MultipleRequest( char const *prompt );
|
||||
int _MultipleRequest( CMultipleParams *params );
|
||||
|
||||
void MultipleRequestChangeContext();
|
||||
|
||||
|
||||
#endif // MULTIPLEREQUEST_H
|
||||
@@ -0,0 +1,416 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "project.h"
|
||||
#include "cmdlib.h"
|
||||
#include <KeyValues.h>
|
||||
#include "scene.h"
|
||||
#include "UtlBuffer.h"
|
||||
#include "vcdfile.h"
|
||||
#include "workspacemanager.h"
|
||||
#include "workspacebrowser.h"
|
||||
|
||||
CProject::CProject( CWorkspace *ws, char const *filename ) : m_pOwner( ws )
|
||||
{
|
||||
Q_strncpy( m_szFile, filename, sizeof( m_szFile ) );
|
||||
// By default, name is the same as the filename
|
||||
Q_FileBase( m_szFile, m_szName, sizeof( m_szName ) );
|
||||
|
||||
m_bDirty = false;
|
||||
m_pszComments = NULL;
|
||||
|
||||
LoadFromFile();
|
||||
}
|
||||
|
||||
CProject::~CProject()
|
||||
{
|
||||
while ( m_Scenes.Count() > 0 )
|
||||
{
|
||||
CScene *p = m_Scenes[ 0 ];
|
||||
m_Scenes.Remove( 0 );
|
||||
delete p;
|
||||
}
|
||||
delete[] m_pszComments;
|
||||
}
|
||||
|
||||
CWorkspace *CProject::GetOwnerWorkspace()
|
||||
{
|
||||
return m_pOwner;
|
||||
}
|
||||
|
||||
char const *CProject::GetName() const
|
||||
{
|
||||
return m_szName;
|
||||
}
|
||||
|
||||
char const *CProject::GetFileName() const
|
||||
{
|
||||
return m_szFile;
|
||||
}
|
||||
|
||||
bool CProject::IsDirty( void ) const
|
||||
{
|
||||
return m_bDirty;
|
||||
}
|
||||
|
||||
void CProject::SetDirty( bool dirty )
|
||||
{
|
||||
m_bDirty = dirty;
|
||||
}
|
||||
|
||||
void CProject::SetComments( char const *comments )
|
||||
{
|
||||
delete[] m_pszComments;
|
||||
m_pszComments = V_strdup( comments );
|
||||
|
||||
SetDirty( true );
|
||||
}
|
||||
|
||||
char const *CProject::GetComments() const
|
||||
{
|
||||
return m_pszComments ? m_pszComments : "";
|
||||
}
|
||||
|
||||
int CProject::GetSceneCount() const
|
||||
{
|
||||
return m_Scenes.Count();
|
||||
}
|
||||
|
||||
CScene *CProject::GetScene( int index ) const
|
||||
{
|
||||
if ( index < 0 || index >= m_Scenes.Count() )
|
||||
return NULL;
|
||||
return m_Scenes[ index ];
|
||||
}
|
||||
|
||||
void CProject::AddScene( CScene *scene )
|
||||
{
|
||||
SetDirty( true );
|
||||
|
||||
Assert( m_Scenes.Find( scene ) == m_Scenes.InvalidIndex() );
|
||||
|
||||
m_Scenes.AddToTail( scene );
|
||||
}
|
||||
|
||||
void CProject::RemoveScene( CScene *scene )
|
||||
{
|
||||
if ( m_Scenes.Find( scene ) == m_Scenes.InvalidIndex() )
|
||||
return;
|
||||
|
||||
m_Scenes.FindAndRemove( scene );
|
||||
SetDirty( true );
|
||||
}
|
||||
|
||||
void CProject::LoadFromFile()
|
||||
{
|
||||
KeyValues *kv = new KeyValues( m_szName );
|
||||
if ( kv->LoadFromFile( filesystem, m_szFile ) )
|
||||
{
|
||||
for ( KeyValues *s = kv->GetFirstSubKey(); s; s = s->GetNextKey() )
|
||||
{
|
||||
if ( !Q_stricmp( s->GetName(), "comments" ) )
|
||||
{
|
||||
SetComments( s->GetString() );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add named scenes
|
||||
CScene *scene = new CScene( this, s->GetName() );
|
||||
|
||||
for ( KeyValues *sub = s->GetFirstSubKey(); sub; sub = sub->GetNextKey() )
|
||||
{
|
||||
if ( !Q_stricmp( sub->GetName(), "comments" ) )
|
||||
{
|
||||
scene->SetComments( sub->GetString() );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( sub->GetName(), "expanded" ) )
|
||||
{
|
||||
scene->SetExpanded( sub->GetInt() ? true : false );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !Q_stricmp( sub->GetName(), "vcd" ) )
|
||||
{
|
||||
char filename[ 256 ];
|
||||
char comments[ 512 ];
|
||||
bool expanded = false;
|
||||
|
||||
filename[ 0 ] = 0;
|
||||
comments[ 0 ] = 0;
|
||||
|
||||
for ( KeyValues *vcdKeys = sub->GetFirstSubKey(); vcdKeys; vcdKeys = vcdKeys->GetNextKey() )
|
||||
{
|
||||
if ( !Q_stricmp( vcdKeys->GetName(), "expanded" ) )
|
||||
{
|
||||
expanded = vcdKeys->GetInt() ? true : false;
|
||||
continue;
|
||||
}
|
||||
else if ( !Q_stricmp( vcdKeys->GetName(), "file" ) )
|
||||
{
|
||||
Q_strncpy( filename, vcdKeys->GetString(), sizeof( filename ) );
|
||||
continue;
|
||||
}
|
||||
if ( !Q_stricmp( vcdKeys->GetName(), "comments" ) )
|
||||
{
|
||||
Q_strncpy( comments, vcdKeys->GetString(), sizeof( comments ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
Assert( 0 );
|
||||
|
||||
}
|
||||
|
||||
CVCDFile *file = new CVCDFile( scene, filename);
|
||||
file->SetExpanded( expanded );
|
||||
if ( comments[0] )
|
||||
{
|
||||
file->SetComments( comments );
|
||||
}
|
||||
|
||||
scene->AddVCD( file );
|
||||
continue;
|
||||
}
|
||||
|
||||
Assert( !va( "Unknown scene token %s\n", sub->GetName() ) );
|
||||
}
|
||||
|
||||
m_Scenes.AddToTail( scene );
|
||||
}
|
||||
}
|
||||
kv->deleteThis();
|
||||
|
||||
SetDirty( false );
|
||||
}
|
||||
|
||||
void CProject::SaveToFile()
|
||||
{
|
||||
SetDirty( false );
|
||||
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
|
||||
buf.Printf( "%s\n{\n", GetName() );
|
||||
|
||||
if ( GetComments() && GetComments()[0] )
|
||||
{
|
||||
buf.Printf( "\t\"comments\"\t\"%s\"\n",
|
||||
GetComments() );
|
||||
}
|
||||
|
||||
// walk projects
|
||||
int c = GetSceneCount();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
CScene *scene = GetScene( i );
|
||||
Assert( scene );
|
||||
|
||||
buf.Printf( "\t\"%s\"\n", scene->GetName() );
|
||||
buf.Printf( "\t{\n" );
|
||||
|
||||
buf.Printf( "\t\t\"expanded\"\t\"%i\"\n", scene->IsExpanded() ? 1 : 0 );
|
||||
|
||||
if ( scene->GetComments() && scene->GetComments()[0] )
|
||||
{
|
||||
buf.Printf( "\t\t\"comments\"\t\"%s\"\n",
|
||||
scene->GetComments() );
|
||||
}
|
||||
|
||||
int vcdcount = scene->GetVCDCount();
|
||||
for ( int j = 0; j < vcdcount; j++ )
|
||||
{
|
||||
CVCDFile *vcd = scene->GetVCD( j );
|
||||
Assert( vcd );
|
||||
|
||||
buf.Printf( "\t\tvcd\n" );
|
||||
buf.Printf( "\t\t{\n" );
|
||||
|
||||
buf.Printf( "\t\t\t\"expanded\"\t\"%i\"\n",
|
||||
vcd->IsExpanded() ? 1 : 0 );
|
||||
buf.Printf( "\t\t\t\"file\"\t\"%s\"\n",
|
||||
vcd->GetName() );
|
||||
if ( vcd->GetComments() && vcd->GetComments()[0] )
|
||||
{
|
||||
buf.Printf( "\t\t\t\"comments\"\t\"%s\"\n",
|
||||
vcd->GetComments() );
|
||||
}
|
||||
|
||||
buf.Printf( "\t\t}\n" );
|
||||
}
|
||||
|
||||
buf.Printf( "\t}\n" );
|
||||
|
||||
if ( i != c - 1 )
|
||||
{
|
||||
buf.Printf( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
buf.Printf( "}\n" );
|
||||
|
||||
// Write it out baby
|
||||
FileHandle_t fh = filesystem->Open( m_szFile, "wt" );
|
||||
if (fh)
|
||||
{
|
||||
filesystem->Write( buf.Base(), buf.TellPut(), fh );
|
||||
filesystem->Close(fh);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( "CWorkspace::SaveToFile: Unable to write file %s!!!\n", m_szFile );
|
||||
}
|
||||
}
|
||||
|
||||
void CProject::SaveChanges()
|
||||
{
|
||||
if ( !IsDirty() )
|
||||
return;
|
||||
|
||||
SaveToFile();
|
||||
}
|
||||
|
||||
void CProject::ValidateTree( mxTreeView *tree, mxTreeViewItem* parent )
|
||||
{
|
||||
CUtlVector< mxTreeViewItem * > m_KnownItems;
|
||||
|
||||
int c = GetSceneCount();
|
||||
CScene *scene;
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
scene = GetScene( i );
|
||||
if ( !scene )
|
||||
continue;
|
||||
|
||||
char sz[ 256 ];
|
||||
if ( scene->GetComments() && scene->GetComments()[0] )
|
||||
{
|
||||
Q_snprintf( sz, sizeof( sz ) , "%s : %s", scene->GetName(), scene->GetComments() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( sz, sizeof( sz ) , "%s", scene->GetName() );
|
||||
}
|
||||
|
||||
|
||||
mxTreeViewItem *spot = scene->FindItem( tree, parent );
|
||||
if ( !spot )
|
||||
{
|
||||
spot = tree->add( parent, sz );
|
||||
}
|
||||
|
||||
m_KnownItems.AddToTail( spot );
|
||||
|
||||
scene->SetOrdinal( i );
|
||||
|
||||
tree->setLabel( spot, sz );
|
||||
|
||||
tree->setImages( spot, scene->GetIconIndex(), scene->GetIconIndex() );
|
||||
tree->setUserData( spot, scene );
|
||||
//tree->setOpen( spot, scene->IsExpanded() );
|
||||
|
||||
scene->ValidateTree( tree, spot );
|
||||
}
|
||||
|
||||
mxTreeViewItem *start = tree->getFirstChild( parent );
|
||||
while ( start )
|
||||
{
|
||||
mxTreeViewItem *next = tree->getNextChild( start );
|
||||
|
||||
if ( m_KnownItems.Find( start ) == m_KnownItems.InvalidIndex() )
|
||||
{
|
||||
tree->remove( start );
|
||||
}
|
||||
|
||||
start = next;
|
||||
}
|
||||
|
||||
tree->sortTree( parent, true, CWorkspaceBrowser::CompareFunc, 0 );
|
||||
}
|
||||
|
||||
void CProject::Checkout(bool updatestateicons /*= true*/)
|
||||
{
|
||||
VSS_Checkout( GetFileName(), updatestateicons );
|
||||
}
|
||||
|
||||
void CProject::Checkin(bool updatestateicons /*= true*/)
|
||||
{
|
||||
VSS_Checkin( GetFileName(), updatestateicons );
|
||||
}
|
||||
|
||||
bool CProject::IsCheckedOut() const
|
||||
{
|
||||
return filesystem->IsFileWritable( GetFileName() );
|
||||
}
|
||||
|
||||
int CProject::GetIconIndex() const
|
||||
{
|
||||
if ( IsCheckedOut() )
|
||||
{
|
||||
return IMAGE_PROJECT_CHECKEDOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IMAGE_PROJECT;
|
||||
}
|
||||
}
|
||||
|
||||
bool CProject::IsChildFirst( ITreeItem *child )
|
||||
{
|
||||
int idx = m_Scenes.Find( (CScene *)child );
|
||||
if ( idx == m_Scenes.InvalidIndex() )
|
||||
return false;
|
||||
|
||||
if ( idx != 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CProject::IsChildLast( ITreeItem *child )
|
||||
{
|
||||
int idx = m_Scenes.Find( (CScene *)child );
|
||||
if ( idx == m_Scenes.InvalidIndex() )
|
||||
return false;
|
||||
|
||||
if ( idx != m_Scenes.Count() - 1 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CProject::MoveChildUp( ITreeItem *child )
|
||||
{
|
||||
int c = GetSceneCount();
|
||||
for ( int i = 1; i < c; i++ )
|
||||
{
|
||||
CScene *p = GetScene( i );
|
||||
if ( p != child )
|
||||
continue;
|
||||
|
||||
CScene *prev = GetScene( i - 1 );
|
||||
// Swap
|
||||
m_Scenes[ i - 1 ] = p;
|
||||
m_Scenes[ i ] = prev;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CProject::MoveChildDown( ITreeItem *child )
|
||||
{
|
||||
int c = GetSceneCount();
|
||||
for ( int i = 0; i < c - 1; i++ )
|
||||
{
|
||||
CScene *p = GetScene( i );
|
||||
if ( p != child )
|
||||
continue;
|
||||
|
||||
CScene *next = GetScene( i + 1 );
|
||||
// Swap
|
||||
m_Scenes[ i ] = next;
|
||||
m_Scenes[ i + 1 ] = p;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PROJECT_H
|
||||
#define PROJECT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CScene;
|
||||
class mxTreeView;
|
||||
class CWorkspace;
|
||||
|
||||
#include "itreeitem.h"
|
||||
|
||||
class CProject : public ITreeItem
|
||||
{
|
||||
public:
|
||||
CProject( CWorkspace *ws, char const *filename );
|
||||
~CProject();
|
||||
|
||||
CWorkspace *GetOwnerWorkspace();
|
||||
|
||||
char const *GetName() const;
|
||||
char const *GetFileName() const;
|
||||
|
||||
|
||||
bool IsDirty( void ) const;
|
||||
void SetDirty( bool dirty );
|
||||
|
||||
void SetComments( char const *comments );
|
||||
char const *GetComments( void ) const;
|
||||
|
||||
int GetSceneCount() const;
|
||||
CScene *GetScene( int index ) const;
|
||||
void AddScene( CScene *scene );
|
||||
void RemoveScene( CScene *scene );
|
||||
|
||||
void ValidateTree( mxTreeView *tree, mxTreeViewItem* parent );
|
||||
|
||||
void SaveChanges();
|
||||
|
||||
virtual CWorkspace *GetWorkspace() { return NULL; }
|
||||
virtual CProject *GetProject() { return this; }
|
||||
virtual CScene *GetScene() { return NULL; }
|
||||
virtual CVCDFile *GetVCDFile() { return NULL; }
|
||||
virtual CSoundEntry *GetSoundEntry() { return NULL; }
|
||||
virtual CWaveFile *GetWaveFile() { return NULL; }
|
||||
|
||||
virtual void Checkout( bool updatestateicons = true );
|
||||
virtual void Checkin( bool updatestateicons = true );
|
||||
|
||||
bool IsCheckedOut() const;
|
||||
int GetIconIndex() const;
|
||||
|
||||
virtual void MoveChildUp( ITreeItem *child );
|
||||
virtual void MoveChildDown( ITreeItem *child );
|
||||
|
||||
virtual bool IsChildFirst( ITreeItem *child );
|
||||
virtual bool IsChildLast( ITreeItem *child );
|
||||
|
||||
private:
|
||||
|
||||
void LoadFromFile();
|
||||
void SaveToFile();
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_PROJECT_NAME = 128,
|
||||
MAX_PROJECT_FILENAME = 256
|
||||
};
|
||||
|
||||
char m_szName[ MAX_PROJECT_NAME ];
|
||||
char m_szFile[ MAX_PROJECT_FILENAME ];
|
||||
|
||||
char *m_pszComments;
|
||||
|
||||
bool m_bDirty;
|
||||
|
||||
CUtlVector< CScene * > m_Scenes;
|
||||
|
||||
CWorkspace *m_pOwner;
|
||||
};
|
||||
|
||||
#endif // PROJECT_H
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,72 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by scenemanager.rc
|
||||
//
|
||||
#define IDC_NOSINGLE 3
|
||||
#define IDC_NOALL 4
|
||||
#define IDI_PLUS 104
|
||||
#define IDI_WORKSPACE 104
|
||||
#define IDI_MINUS 105
|
||||
#define IDI_PROJECT 105
|
||||
#define IDI_SCENE 106
|
||||
#define IDI_VCD 107
|
||||
#define IDI_WAV 108
|
||||
#define IDI_SPEAK 109
|
||||
#define IDD_INPUTDIALOG 110
|
||||
#define IDI_SPEAK_CHECKEDOUT 112
|
||||
#define IDI_WAV_CHECKEDOUT 113
|
||||
#define IDD_VSSPROPERTIES 113
|
||||
#define IDI_WORKSPACE_CHECKEDOUT 114
|
||||
#define IDI_VCD_CHECKEDOUT 115
|
||||
#define IDI_PROJECT_CHECKEDOUT 116
|
||||
#define IDD_SOUNDPROPERTIES 117
|
||||
#define IDD_WAVEPROPERTIES 118
|
||||
#define IDD_SOUNDPROPERTIES_MULTIPLE 119
|
||||
#define IDD_MULTIPLEQUESTION 120
|
||||
#define IDC_INPUTSTRING 1000
|
||||
#define IDC_STATIC_PROMPT 1001
|
||||
#define IDC_VSS_USERNAME 1002
|
||||
#define IDC_VSS_PROJECT 1003
|
||||
#define IDC_SOUNDNAME 1004
|
||||
#define IDC_SOUNDSCRIPT 1005
|
||||
#define IDC_CHANNEL 1007
|
||||
#define IDC_VOLUME 1008
|
||||
#define IDC_SOUNDLEVEL 1009
|
||||
#define IDC_PITCH 1010
|
||||
#define IDC_WAVELIST 1013
|
||||
#define IDC_ADDWAVE 1014
|
||||
#define IDC_REMOVEWAVE 1015
|
||||
#define IDC_WAVELIST_AVAILABLE 1016
|
||||
#define IDC_OWNERONLY 1017
|
||||
#define IDC_STATIC_SENTENCETEXT 1018
|
||||
#define IDC_WAVENAME 1019
|
||||
#define IDC_STATIC_CLOSECAPTION 1019
|
||||
#define IDC_VOICEDUCK 1020
|
||||
#define IDC_SENTENCETEXT 1021
|
||||
#define IDC_WAVEPROPERTIES 1022
|
||||
#define IDC_CCTEXT 1022
|
||||
#define IDC_PROMPT 1023
|
||||
#define IDC_YESALL 1024
|
||||
#define IDC_YES 1025
|
||||
#define IDC_CCRESET 1026
|
||||
#define IDC_EXPORTSENTENCE 1027
|
||||
#define IDC_IMPORTSENTENCE 1028
|
||||
#define IDC_STATIC_CCTEXT 1029
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 121
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1030
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,243 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "scene.h"
|
||||
#include "vcdfile.h"
|
||||
#include "project.h"
|
||||
#include "workspacemanager.h"
|
||||
#include "workspacebrowser.h"
|
||||
|
||||
CScene::CScene( CProject *proj, char const *name ) : m_pOwner( proj )
|
||||
{
|
||||
Q_strncpy( m_szName, name, sizeof( m_szName ) );
|
||||
m_pszComments = NULL;
|
||||
}
|
||||
|
||||
CScene::~CScene()
|
||||
{
|
||||
while ( m_Files.Count() > 0 )
|
||||
{
|
||||
CVCDFile *f = m_Files[ 0 ];
|
||||
m_Files.Remove( 0 );
|
||||
delete f;
|
||||
}
|
||||
delete[] m_pszComments;
|
||||
}
|
||||
|
||||
CProject *CScene::GetOwnerProject()
|
||||
{
|
||||
return m_pOwner;
|
||||
}
|
||||
|
||||
void CScene::SetComments( char const *comments )
|
||||
{
|
||||
delete[] m_pszComments;
|
||||
m_pszComments = V_strdup( comments );
|
||||
|
||||
GetOwnerProject()->SetDirty( true );
|
||||
}
|
||||
|
||||
char const *CScene::GetComments( void ) const
|
||||
{
|
||||
return m_pszComments ? m_pszComments : "";
|
||||
}
|
||||
|
||||
char const *CScene::GetName() const
|
||||
{
|
||||
return m_szName;
|
||||
}
|
||||
|
||||
int CScene::GetVCDCount() const
|
||||
{
|
||||
return m_Files.Count();
|
||||
}
|
||||
|
||||
CVCDFile *CScene::GetVCD( int index )
|
||||
{
|
||||
if ( index < 0 || index >= m_Files.Count() )
|
||||
return NULL;
|
||||
return m_Files[ index ];
|
||||
}
|
||||
|
||||
void CScene::AddVCD( CVCDFile *vcd )
|
||||
{
|
||||
Assert( m_Files.Find( vcd ) == m_Files.InvalidIndex() );
|
||||
|
||||
m_Files.AddToTail( vcd );
|
||||
|
||||
GetOwnerProject()->SetDirty( true );
|
||||
}
|
||||
|
||||
void CScene::RemoveVCD( CVCDFile *vcd )
|
||||
{
|
||||
if ( m_Files.Find( vcd ) == m_Files.InvalidIndex() )
|
||||
return;
|
||||
|
||||
m_Files.FindAndRemove( vcd );
|
||||
|
||||
GetOwnerProject()->SetDirty( true );
|
||||
}
|
||||
|
||||
CVCDFile *CScene::FindVCD( char const *filename )
|
||||
{
|
||||
int c = GetVCDCount();
|
||||
CVCDFile *vcd;
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
vcd = GetVCD( i );
|
||||
if ( !vcd )
|
||||
continue;
|
||||
|
||||
if ( !Q_stricmp( filename, vcd->GetName() ) )
|
||||
return vcd;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CScene::ValidateTree( mxTreeView *tree, mxTreeViewItem* parent )
|
||||
{
|
||||
CUtlVector< mxTreeViewItem * > m_KnownItems;
|
||||
|
||||
int c = GetVCDCount();
|
||||
CVCDFile *vcd;
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
vcd = GetVCD( i );
|
||||
if ( !vcd )
|
||||
continue;
|
||||
|
||||
char sz[ 256 ];
|
||||
if ( vcd->GetComments() && vcd->GetComments()[0] )
|
||||
{
|
||||
Q_snprintf( sz, sizeof( sz ), "%s : %s", vcd->GetName(), vcd->GetComments() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( sz, sizeof( sz ), "%s", vcd->GetName() );
|
||||
}
|
||||
|
||||
mxTreeViewItem *spot = vcd->FindItem( tree, parent );
|
||||
if ( !spot )
|
||||
{
|
||||
spot = tree->add( parent, sz );
|
||||
}
|
||||
|
||||
m_KnownItems.AddToTail( spot );
|
||||
|
||||
vcd->SetOrdinal( i );
|
||||
|
||||
tree->setLabel( spot, sz );
|
||||
|
||||
tree->setImages( spot, vcd->GetIconIndex(), vcd->GetIconIndex() );
|
||||
tree->setUserData( spot, vcd );
|
||||
//tree->setOpen( spot, vcd->IsExpanded() );
|
||||
|
||||
vcd->ValidateTree( tree, spot );
|
||||
}
|
||||
|
||||
mxTreeViewItem *start = tree->getFirstChild( parent );
|
||||
while ( start )
|
||||
{
|
||||
mxTreeViewItem *next = tree->getNextChild( start );
|
||||
|
||||
if ( m_KnownItems.Find( start ) == m_KnownItems.InvalidIndex() )
|
||||
{
|
||||
tree->remove( start );
|
||||
}
|
||||
|
||||
start = next;
|
||||
}
|
||||
|
||||
tree->sortTree( parent, true, CWorkspaceBrowser::CompareFunc, 0 );
|
||||
}
|
||||
|
||||
bool CScene::IsCheckedOut() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int CScene::GetIconIndex() const
|
||||
{
|
||||
/*
|
||||
if ( IsCheckedOut() )
|
||||
{
|
||||
return IMAGE_SCENE_CHECKEDOUT;
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
return IMAGE_SCENE;
|
||||
}
|
||||
}
|
||||
|
||||
void CScene::Checkout(bool updatestateicons /*= true*/)
|
||||
{
|
||||
// Scenes aren't made for checkin / checkout
|
||||
}
|
||||
|
||||
void CScene::Checkin(bool updatestateicons /*= true*/)
|
||||
{
|
||||
// Scenes aren't made for checkin / checkout
|
||||
}
|
||||
|
||||
void CScene::MoveChildUp( ITreeItem *child )
|
||||
{
|
||||
int c = GetVCDCount();
|
||||
for ( int i = 1; i < c; i++ )
|
||||
{
|
||||
CVCDFile *p = GetVCD( i );
|
||||
if ( p != child )
|
||||
continue;
|
||||
|
||||
CVCDFile *prev = GetVCD( i - 1 );
|
||||
// Swap
|
||||
m_Files[ i - 1 ] = p;
|
||||
m_Files[ i ] = prev;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CScene::MoveChildDown( ITreeItem *child )
|
||||
{
|
||||
int c = GetVCDCount();
|
||||
for ( int i = 0; i < c - 1; i++ )
|
||||
{
|
||||
CVCDFile *p = GetVCD( i );
|
||||
if ( p != child )
|
||||
continue;
|
||||
|
||||
CVCDFile *next = GetVCD( i + 1 );
|
||||
// Swap
|
||||
m_Files[ i ] = next;
|
||||
m_Files[ i + 1 ] = p;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool CScene::IsChildFirst( ITreeItem *child )
|
||||
{
|
||||
int idx = m_Files.Find( (CVCDFile *)child );
|
||||
if ( idx == m_Files.InvalidIndex() )
|
||||
return false;
|
||||
|
||||
if ( idx != 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CScene::IsChildLast( ITreeItem *child )
|
||||
{
|
||||
int idx = m_Files.Find( (CVCDFile *)child );
|
||||
if ( idx == m_Files.InvalidIndex() )
|
||||
return false;
|
||||
|
||||
if ( idx != m_Files.Count() - 1 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SCENE_H
|
||||
#define SCENE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CVCDFile;
|
||||
class CProject;
|
||||
|
||||
#include "itreeitem.h"
|
||||
|
||||
class CScene : public ITreeItem
|
||||
{
|
||||
public:
|
||||
CScene( CProject *proj, char const *name );
|
||||
~CScene();
|
||||
|
||||
CProject *GetOwnerProject();
|
||||
|
||||
void SetComments( char const *comments );
|
||||
char const *GetComments( void ) const;
|
||||
char const *GetName() const;
|
||||
|
||||
int GetVCDCount() const;
|
||||
CVCDFile *GetVCD( int index );
|
||||
void AddVCD( CVCDFile *vcd );
|
||||
void RemoveVCD( CVCDFile *vcd );
|
||||
CVCDFile *FindVCD( char const *filename );
|
||||
|
||||
void ValidateTree( mxTreeView *tree, mxTreeViewItem* parent );
|
||||
|
||||
virtual CWorkspace *GetWorkspace() { return NULL; }
|
||||
virtual CProject *GetProject() { return NULL; }
|
||||
virtual CScene *GetScene() { return this; }
|
||||
virtual CVCDFile *GetVCDFile() { return NULL; }
|
||||
virtual CSoundEntry *GetSoundEntry() { return NULL; }
|
||||
virtual CWaveFile *GetWaveFile() { return NULL; }
|
||||
|
||||
bool IsCheckedOut() const;
|
||||
int GetIconIndex() const;
|
||||
|
||||
virtual void Checkout( bool updatestateicons = true );
|
||||
virtual void Checkin( bool updatestateicons = true );
|
||||
|
||||
virtual void MoveChildUp( ITreeItem *child );
|
||||
virtual void MoveChildDown( ITreeItem *child );
|
||||
|
||||
void SetDirty( bool dirty )
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool IsChildFirst( ITreeItem *child );
|
||||
virtual bool IsChildLast( ITreeItem *child );
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
MAX_SCENE_NAME = 128,
|
||||
};
|
||||
|
||||
char m_szName[ MAX_SCENE_NAME ];
|
||||
char *m_pszComments;
|
||||
|
||||
CUtlVector< CVCDFile * > m_Files;
|
||||
|
||||
CProject *m_pOwner;
|
||||
};
|
||||
|
||||
#endif // SCENE_H
|
||||
@@ -0,0 +1,220 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
// scenemanager.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "appframework/tier3app.h"
|
||||
#include "workspacemanager.h"
|
||||
#include "filesystem.h"
|
||||
#include "FileSystem_Tools.h"
|
||||
#include "cmdlib.h"
|
||||
#include "vstdlib/random.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "iscenemanagersound.h"
|
||||
#include <vgui/ILocalize.h>
|
||||
#include <vgui/IVGui.h>
|
||||
#include "tier0/icommandline.h"
|
||||
#include "icvar.h"
|
||||
#include "vstdlib/cvar.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
char cmdline[1024] = "";
|
||||
|
||||
static CUniformRandomStream g_Random;
|
||||
IUniformRandomStream *random = &g_Random;
|
||||
|
||||
IFileSystem *filesystem = NULL;
|
||||
|
||||
SpewRetval_t SceneManagerSpewFunc( SpewType_t spewType, char const *pMsg )
|
||||
{
|
||||
switch (spewType)
|
||||
{
|
||||
case SPEW_ERROR:
|
||||
{
|
||||
MessageBox(NULL, pMsg, "FATAL ERROR", MB_OK);
|
||||
}
|
||||
return SPEW_ABORT;
|
||||
case SPEW_WARNING:
|
||||
{
|
||||
Con_ColorPrintf( 255, 0, 0, pMsg );
|
||||
}
|
||||
break;
|
||||
case SPEW_ASSERT:
|
||||
{
|
||||
Con_ColorPrintf( 255, 0, 0, pMsg );
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
return SPEW_DEBUGGER;
|
||||
#else
|
||||
return SPEW_CONTINUE;
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
Con_Printf(pMsg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return SPEW_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The application object
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHLSceneManagerApp : public CTier3SteamApp
|
||||
{
|
||||
typedef CTier3SteamApp BaseClass;
|
||||
|
||||
public:
|
||||
// Methods of IApplication
|
||||
virtual bool Create();
|
||||
virtual bool PreInit();
|
||||
virtual int Main();
|
||||
virtual void PostShutdown();
|
||||
virtual void Destroy();
|
||||
|
||||
private:
|
||||
// Sets up the search paths
|
||||
bool SetupSearchPaths();
|
||||
};
|
||||
|
||||
|
||||
bool CHLSceneManagerApp::Create()
|
||||
{
|
||||
SpewOutputFunc( SceneManagerSpewFunc );
|
||||
|
||||
AppSystemInfo_t appSystems[] =
|
||||
{
|
||||
{ "vgui2.dll", VGUI_IVGUI_INTERFACE_VERSION },
|
||||
{ "soundemittersystem.dll", SOUNDEMITTERSYSTEM_INTERFACE_VERSION },
|
||||
|
||||
{ "", "" } // Required to terminate the list
|
||||
};
|
||||
|
||||
return AddSystems( appSystems );
|
||||
}
|
||||
|
||||
void CHLSceneManagerApp::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up the game path
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHLSceneManagerApp::SetupSearchPaths()
|
||||
{
|
||||
if ( !BaseClass::SetupSearchPaths( NULL, false, true ) )
|
||||
return false;
|
||||
|
||||
// Set gamedir.
|
||||
Q_MakeAbsolutePath( gamedir, sizeof( gamedir ), GetGameInfoPath() );
|
||||
Q_AppendSlash( gamedir, sizeof( gamedir ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Init, shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHLSceneManagerApp::PreInit( )
|
||||
{
|
||||
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
|
||||
|
||||
if ( !BaseClass::PreInit() )
|
||||
return false;
|
||||
|
||||
g_pFileSystem = filesystem = g_pFullFileSystem;
|
||||
if ( !g_pSoundEmitterSystem || !g_pVGuiLocalize || !g_pFileSystem )
|
||||
{
|
||||
Error("Unable to load required library interface!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
filesystem->SetWarningFunc( Warning );
|
||||
|
||||
// Add paths...
|
||||
if ( !SetupSearchPaths() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CHLSceneManagerApp::PostShutdown()
|
||||
{
|
||||
g_pFileSystem = filesystem = NULL;
|
||||
BaseClass::PostShutdown();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// main application
|
||||
//-----------------------------------------------------------------------------
|
||||
int CHLSceneManagerApp::Main()
|
||||
{
|
||||
g_pSoundEmitterSystem->ModInit();
|
||||
|
||||
sound->Init();
|
||||
|
||||
CWorkspaceManager *sm = new CWorkspaceManager();
|
||||
|
||||
bool workspace_loaded = false;
|
||||
for ( int i = 1; i < CommandLine()->ParmCount(); i++ )
|
||||
{
|
||||
char const *argv = CommandLine()->GetParm( i );
|
||||
|
||||
if ( !workspace_loaded && strstr (argv, ".vsw") )
|
||||
{
|
||||
workspace_loaded = true;
|
||||
|
||||
// Strip game directory and slash
|
||||
char workspace_name[ 512 ];
|
||||
filesystem->FullPathToRelativePath( argv, workspace_name, sizeof( workspace_name ) );
|
||||
|
||||
sm->AutoLoad( workspace_name );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !workspace_loaded )
|
||||
{
|
||||
sm->AutoLoad( NULL );
|
||||
}
|
||||
|
||||
int retval = mx::run ();
|
||||
|
||||
sound->Shutdown();
|
||||
|
||||
g_pSoundEmitterSystem->ModShutdown();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
CommandLine()->CreateCmdLine( argc, argv );
|
||||
CoInitialize(NULL);
|
||||
|
||||
// make sure, we start in the right directory
|
||||
char szName[256];
|
||||
strcpy (szName, mx::getApplicationPath() );
|
||||
mx::init (argc, argv);
|
||||
|
||||
char workingdir[ 256 ];
|
||||
workingdir[0] = 0;
|
||||
Q_getwd( workingdir, sizeof( workingdir ) );
|
||||
|
||||
CHLSceneManagerApp sceneManagerApp;
|
||||
CSteamApplication steamApplication( &sceneManagerApp );
|
||||
int nRetVal = steamApplication.Run();
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
return nRetVal;
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_WORKSPACE ICON DISCARDABLE "icon1.ico"
|
||||
MX_ICON ICON DISCARDABLE "ico00006.ico"
|
||||
IDI_SCENE ICON DISCARDABLE "ico00002.ico"
|
||||
IDI_VCD ICON DISCARDABLE "ico00003.ico"
|
||||
IDI_WAV ICON DISCARDABLE "ico00004.ico"
|
||||
IDI_SPEAK ICON DISCARDABLE "ico00005.ico"
|
||||
IDI_SPEAK_CHECKEDOUT ICON DISCARDABLE "ico00007.ico"
|
||||
IDI_WAV_CHECKEDOUT ICON DISCARDABLE "wav1.ico"
|
||||
IDI_WORKSPACE_CHECKEDOUT ICON DISCARDABLE "workspac.ico"
|
||||
IDI_VCD_CHECKEDOUT ICON DISCARDABLE "vcd1.ico"
|
||||
IDI_PROJECT ICON DISCARDABLE "ico00001.ico"
|
||||
IDI_PROJECT_CHECKEDOUT ICON DISCARDABLE "project1.ico"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_INPUTDIALOG DIALOG DISCARDABLE 0, 0, 361, 73
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Input:"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,128,47,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,186,47,50,14
|
||||
EDITTEXT IDC_INPUTSTRING,7,25,347,14,ES_AUTOHSCROLL
|
||||
LTEXT "Static",IDC_STATIC_PROMPT,7,7,347,16
|
||||
END
|
||||
|
||||
IDD_VSSPROPERTIES DIALOG DISCARDABLE 0, 0, 246, 82
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,189,7,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,189,24,50,14
|
||||
LTEXT "VSS User Name:",IDC_STATIC,7,7,106,10
|
||||
EDITTEXT IDC_VSS_USERNAME,7,22,164,14,ES_AUTOHSCROLL
|
||||
LTEXT "VSS Project: e.g., $/HL2/release/dev/hl2/",IDC_STATIC,
|
||||
7,42,232,13
|
||||
EDITTEXT IDC_VSS_PROJECT,7,58,232,15,ES_AUTOHSCROLL
|
||||
END
|
||||
|
||||
IDD_SOUNDPROPERTIES DIALOG DISCARDABLE 0, 0, 512, 313
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Sound Properites"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,455,7,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,455,25,50,14
|
||||
LTEXT "Sound Name:",IDC_STATIC,7,7,174,13
|
||||
EDITTEXT IDC_SOUNDNAME,7,19,247,14,ES_AUTOHSCROLL
|
||||
LTEXT "Sound Script File:",IDC_STATIC,7,37,178,12
|
||||
COMBOBOX IDC_SOUNDSCRIPT,7,50,248,89,CBS_DROPDOWN | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
LTEXT "Sentence Text:",IDC_STATIC,131,110,55,12
|
||||
LTEXT "Channel:",IDC_STATIC,269,10,52,13
|
||||
LTEXT "Volume:",IDC_STATIC,269,27,52,13
|
||||
LTEXT "Soundlevel:",IDC_STATIC,269,44,52,13
|
||||
LTEXT "Pitch:",IDC_STATIC,269,61,52,13
|
||||
COMBOBOX IDC_CHANNEL,323,7,110,96,CBS_DROPDOWN | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
COMBOBOX IDC_VOLUME,323,24,110,96,CBS_DROPDOWN | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
COMBOBOX IDC_SOUNDLEVEL,323,41,110,96,CBS_DROPDOWN | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
COMBOBOX IDC_PITCH,323,58,110,96,CBS_DROPDOWN | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
GROUPBOX "Wave Files: ",IDC_STATIC,7,96,498,210
|
||||
LISTBOX IDC_WAVELIST,7,195,210,111,LBS_MULTIPLESEL |
|
||||
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "<- Add",IDC_ADDWAVE,228,198,50,14
|
||||
PUSHBUTTON "Remove ->",IDC_REMOVEWAVE,227,216,50,14
|
||||
CONTROL "Play to Owner Entity Only",IDC_OWNERONLY,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,71,105,10
|
||||
LTEXT "SENTENCE TEXT GOES HERE",IDC_STATIC_SENTENCETEXT,193,
|
||||
110,304,27
|
||||
LTEXT "Members:",IDC_STATIC,11,181,45,10
|
||||
PUSHBUTTON "Properties...",IDC_WAVEPROPERTIES,228,234,50,13
|
||||
LISTBOX IDC_WAVELIST_AVAILABLE,287,195,214,111,LBS_MULTIPLESEL |
|
||||
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Available:",IDC_STATIC,299,181,45,10
|
||||
LTEXT "Close Caption:",IDC_STATIC,132,147,55,12
|
||||
LTEXT "CLOSE CAPTION GOES HERE",IDC_STATIC_CLOSECAPTION,194,
|
||||
147,304,27
|
||||
END
|
||||
|
||||
IDD_WAVEPROPERTIES DIALOG DISCARDABLE 0, 0, 351, 142
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Wave Properites"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,294,7,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,294,25,50,14
|
||||
LTEXT "Wav Name:",-1,7,7,174,13
|
||||
LTEXT "Sentence Text:",-1,7,37,72,12
|
||||
CONTROL "Enable voice ducking",IDC_VOICEDUCK,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,79,105,10
|
||||
LTEXT "WAVE NAME",IDC_WAVENAME,7,20,257,14
|
||||
EDITTEXT IDC_SENTENCETEXT,7,49,337,27,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "Export Sentence Data...",IDC_EXPORTSENTENCE,7,93,91,15
|
||||
PUSHBUTTON "Import Sentence Data...",IDC_IMPORTSENTENCE,7,114,91,15
|
||||
END
|
||||
|
||||
IDD_SOUNDPROPERTIES_MULTIPLE DIALOG DISCARDABLE 0, 0, 263, 126
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Multiple Sound Properites"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,206,7,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,206,25,50,14
|
||||
LTEXT "Channel:",-1,7,10,52,13
|
||||
LTEXT "Volume:",-1,7,27,52,13
|
||||
LTEXT "Soundlevel:",-1,7,44,52,13
|
||||
LTEXT "Pitch:",-1,7,61,52,13
|
||||
COMBOBOX IDC_CHANNEL,61,7,110,96,CBS_DROPDOWN | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
COMBOBOX IDC_VOLUME,61,24,110,96,CBS_DROPDOWN | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
COMBOBOX IDC_SOUNDLEVEL,61,41,110,96,CBS_DROPDOWN | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
COMBOBOX IDC_PITCH,61,58,110,96,CBS_DROPDOWN | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
CONTROL "Play to Owner Entity Only",IDC_OWNERONLY,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,82,105,10
|
||||
END
|
||||
|
||||
IDD_MULTIPLEQUESTION DIALOG DISCARDABLE 0, 0, 351, 59
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Check Out Multiple"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Yes",IDC_YES,122,34,50,14
|
||||
LTEXT "PROMPT GOES HERE",IDC_PROMPT,7,7,337,11
|
||||
PUSHBUTTON "Yes All",IDC_YESALL,66,34,50,14
|
||||
DEFPUSHBUTTON "No",IDC_NOSINGLE,178,34,50,14
|
||||
DEFPUSHBUTTON "No All",IDC_NOALL,234,34,50,14
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO DISCARDABLE
|
||||
BEGIN
|
||||
IDD_INPUTDIALOG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 354
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 66
|
||||
END
|
||||
|
||||
IDD_VSSPROPERTIES, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 239
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 75
|
||||
END
|
||||
|
||||
IDD_SOUNDPROPERTIES, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 505
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 306
|
||||
END
|
||||
|
||||
IDD_WAVEPROPERTIES, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 344
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 135
|
||||
END
|
||||
|
||||
IDD_SOUNDPROPERTIES_MULTIPLE, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 256
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 119
|
||||
END
|
||||
|
||||
IDD_MULTIPLEQUESTION, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 344
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 52
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,261 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// SCENEMANAGER.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,..\common,$SRCDIR\game\shared"
|
||||
$PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE"
|
||||
$Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)"
|
||||
$Create/UsePCHThroughFile "cbase.h"
|
||||
$PrecompiledHeaderFile "Debug/scenemanager.pch"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE Winmm.lib Msimg32.lib comctl32.lib odbc32.lib odbccp32.lib"
|
||||
$EntryPoint "mainCRTStartup"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Scenemanager"
|
||||
{
|
||||
$Folder "Precompiled Header"
|
||||
{
|
||||
$File "cbase.cpp"
|
||||
{
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$Create/UsePrecompiledHeader "Create Precompiled Header (/Yc)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "basedialogparams.cpp"
|
||||
$File "basedialogparams.h"
|
||||
$File "cbase.h"
|
||||
$File "drawhelper.cpp"
|
||||
$File "drawhelper.h"
|
||||
$File "fileloaderthread.cpp"
|
||||
$File "ifileloader.h"
|
||||
$File "inputproperties.cpp"
|
||||
$File "inputproperties.h"
|
||||
$File "itreeitem.h"
|
||||
$File "multiplerequest.cpp"
|
||||
$File "multiplerequest.h"
|
||||
$File "project.cpp"
|
||||
$File "project.h"
|
||||
$File "scene.cpp"
|
||||
$File "scene.h"
|
||||
$File "scenemanager.cpp"
|
||||
$File "scenemanager_tools.cpp"
|
||||
$File "scenemanager_tools.h"
|
||||
$File "soundbrowser.cpp"
|
||||
$File "soundbrowser.h"
|
||||
$File "soundentry.cpp"
|
||||
$File "soundentry.h"
|
||||
$File "$SRCDIR\public\SoundParametersInternal.cpp"
|
||||
$File "soundproperties.cpp"
|
||||
$File "soundproperties.h"
|
||||
$File "soundproperties_multiple.cpp"
|
||||
$File "soundproperties_multiple.h"
|
||||
$File "statuswindow.cpp"
|
||||
$File "statuswindow.h"
|
||||
$File "tabwindow.cpp"
|
||||
$File "tabwindow.h"
|
||||
$File "vcdfile.cpp"
|
||||
$File "vcdfile.h"
|
||||
$File "vssproperties.cpp"
|
||||
$File "vssproperties.h"
|
||||
$File "wavebrowser.cpp"
|
||||
$File "wavebrowser.h"
|
||||
$File "wavefile.cpp"
|
||||
$File "wavefile.h"
|
||||
$File "waveproperties.cpp"
|
||||
$File "waveproperties.h"
|
||||
$File "workspace.cpp"
|
||||
$File "workspace.h"
|
||||
$File "workspacebrowser.cpp"
|
||||
$File "workspacebrowser.h"
|
||||
$File "workspacemanager.cpp"
|
||||
$File "workspacemanager.h"
|
||||
|
||||
$File "..\common\cmdlib.cpp" \
|
||||
"$SRCDIR\public\filesystem_helpers.cpp" \
|
||||
"$SRCDIR\public\filesystem_init.cpp" \
|
||||
"..\common\filesystem_tools.cpp" \
|
||||
"$SRCDIR\public\interpolatortypes.cpp" \
|
||||
"$SRCDIR\game\shared\interval.cpp" \
|
||||
"itreeitem.cpp" \
|
||||
"..\common\scriplib.cpp"
|
||||
{
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$Create/UsePrecompiledHeader "Not Using Precompiled Headers"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$Folder "Resource Files"
|
||||
{
|
||||
$File "ico00001.ico"
|
||||
$File "ico00002.ico"
|
||||
$File "ico00003.ico"
|
||||
$File "ico00004.ico"
|
||||
$File "ico00005.ico"
|
||||
$File "ico00006.ico"
|
||||
$File "ico00007.ico"
|
||||
$File "icon1.ico"
|
||||
$File "project1.ico"
|
||||
$File "resource.h"
|
||||
$File "scenemanager.rc"
|
||||
$File "vcd1.ico"
|
||||
$File "wav1.ico"
|
||||
$File "workspac.ico"
|
||||
}
|
||||
|
||||
$Folder "Public Headers"
|
||||
{
|
||||
$File "$SRCDIR\public\mathlib\amd3dx.h"
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "$SRCDIR\public\tier1\characterset.h"
|
||||
$File "..\common\cmdlib.h"
|
||||
$File "$SRCDIR\public\tier0\commonmacros.h"
|
||||
$File "$SRCDIR\public\tier1\convar.h"
|
||||
$File "$SRCDIR\public\tier0\dbg.h"
|
||||
$File "$SRCDIR\game\shared\ExpressionSample.h"
|
||||
$File "$SRCDIR\public\tier0\fasttimer.h"
|
||||
$File "$SRCDIR\public\filesystem.h"
|
||||
$File "$SRCDIR\public\filesystem_helpers.h"
|
||||
$File "..\common\filesystem_tools.h"
|
||||
$File "$SRCDIR\public\appframework\IAppSystem.h"
|
||||
$File "$SRCDIR\game\shared\ichoreoeventcallback.h"
|
||||
$File "$SRCDIR\public\engine\IEngineSound.h"
|
||||
$File "$SRCDIR\public\tier1\interface.h"
|
||||
$File "$SRCDIR\public\interpolatortypes.h"
|
||||
$File "$SRCDIR\game\shared\interval.h"
|
||||
$File "$SRCDIR\public\irecipientfilter.h"
|
||||
$File "$SRCDIR\game\shared\iscenetokenprocessor.h"
|
||||
$File "$SRCDIR\public\tier1\KeyValues.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
$File "$SRCDIR\public\tier0\mem.h"
|
||||
$File "$SRCDIR\public\tier0\memdbgoff.h"
|
||||
$File "$SRCDIR\public\tier0\memdbgon.h"
|
||||
$File "$SRCDIR\public\tier1\mempool.h"
|
||||
$File "..\..\public\mxtk\mx.h"
|
||||
$File "..\..\public\mxtk\mxButton.h"
|
||||
$File "..\..\public\mxtk\mxCheckBox.h"
|
||||
$File "..\..\public\mxtk\mxChoice.h"
|
||||
$File "..\..\public\mxtk\mxChooseColor.h"
|
||||
$File "..\..\public\mxtk\mxEvent.h"
|
||||
$File "..\..\public\mxtk\mxFileDialog.h"
|
||||
$File "..\..\public\mxtk\mxGlWindow.h"
|
||||
$File "..\..\public\mxtk\mxGroupBox.h"
|
||||
$File "..\..\public\mxtk\mxInit.h"
|
||||
$File "..\..\public\mxtk\mxLabel.h"
|
||||
$File "..\..\public\mxtk\mxLineEdit.h"
|
||||
$File "..\..\public\mxtk\mxLinkedList.h"
|
||||
$File "..\..\public\mxtk\mxListBox.h"
|
||||
$File "..\..\public\mxtk\mxlistview.h"
|
||||
$File "..\..\public\mxtk\mxMenu.h"
|
||||
$File "..\..\public\mxtk\mxMenuBar.h"
|
||||
$File "..\..\public\mxtk\mxMessageBox.h"
|
||||
$File "..\..\public\mxtk\mxpath.h"
|
||||
$File "..\..\public\mxtk\mxPopupMenu.h"
|
||||
$File "..\..\public\mxtk\mxProgressBar.h"
|
||||
$File "..\..\public\mxtk\mxRadioButton.h"
|
||||
$File "..\..\public\mxtk\mxScrollbar.h"
|
||||
$File "..\..\public\mxtk\mxSlider.h"
|
||||
$File "..\..\public\mxtk\mxstring.h"
|
||||
$File "..\..\public\mxtk\mxTab.h"
|
||||
$File "..\..\public\mxtk\mxToggleButton.h"
|
||||
$File "..\..\public\mxtk\mxToolTip.h"
|
||||
$File "..\..\public\mxtk\mxTreeView.h"
|
||||
$File "..\..\public\mxtk\mxWidget.h"
|
||||
$File "..\..\public\mxtk\mxWindow.h"
|
||||
$File "$SRCDIR\public\networkvar.h"
|
||||
$File "$SRCDIR\public\tier0\platform.h"
|
||||
$File "$SRCDIR\public\tier1\processor_detect.h"
|
||||
$File "$SRCDIR\public\tier0\protected_things.h"
|
||||
$File "$SRCDIR\public\vstdlib\random.h"
|
||||
$File "..\common\scriplib.h"
|
||||
$File "$SRCDIR\game\shared\sharedInterface.h"
|
||||
$File "$SRCDIR\public\soundflags.h"
|
||||
$File "$SRCDIR\public\string_t.h"
|
||||
$File "$SRCDIR\public\tier1\strtools.h"
|
||||
$File "$SRCDIR\public\tier1\utlbuffer.h"
|
||||
$File "$SRCDIR\public\tier1\utldict.h"
|
||||
$File "$SRCDIR\public\tier1\utllinkedlist.h"
|
||||
$File "$SRCDIR\public\tier1\utlmemory.h"
|
||||
$File "$SRCDIR\public\tier1\utlrbtree.h"
|
||||
$File "$SRCDIR\public\tier1\utlsymbol.h"
|
||||
$File "$SRCDIR\public\tier1\utlvector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector2d.h"
|
||||
$File "$SRCDIR\public\vstdlib\vstdlib.h"
|
||||
}
|
||||
|
||||
$Folder "Choreography"
|
||||
{
|
||||
$File "$SRCDIR\game\shared\choreoactor.h"
|
||||
$File "$SRCDIR\game\shared\choreochannel.h"
|
||||
$File "$SRCDIR\game\shared\choreoevent.h"
|
||||
$File "$SRCDIR\game\shared\choreoscene.h"
|
||||
}
|
||||
|
||||
$Folder "Audio"
|
||||
{
|
||||
$File "audiowaveoutput.h"
|
||||
$File "iscenemanagersound.h"
|
||||
$File "$SRCDIR\public\sentence.h"
|
||||
$File "snd_audio_source.cpp"
|
||||
$File "snd_audio_source.h"
|
||||
$File "snd_wave_mixer.cpp"
|
||||
$File "snd_wave_mixer.h"
|
||||
$File "snd_wave_mixer_adpcm.cpp"
|
||||
$File "snd_wave_mixer_adpcm.h"
|
||||
$File "snd_wave_mixer_private.h"
|
||||
$File "snd_wave_source.cpp"
|
||||
$File "snd_wave_source.h"
|
||||
$File "sound.cpp"
|
||||
$File "sound.h"
|
||||
|
||||
$File "$SRCDIR\public\sentence.cpp"
|
||||
{
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$Create/UsePrecompiledHeader "Not Using Precompiled Headers"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib appframework
|
||||
$Lib choreoobjects
|
||||
$Lib mathlib
|
||||
$Lib $LIBCOMMON\mxtoolkitwin32
|
||||
$Lib tier2
|
||||
$Lib tier3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,846 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
#include "StatusWindow.h"
|
||||
#include "cmdlib.h"
|
||||
#include <sys/stat.h>
|
||||
#include "workspace.h"
|
||||
#include "workspacemanager.h"
|
||||
#include "workspacebrowser.h"
|
||||
#include "tier2/riff.h"
|
||||
#include "sentence.h"
|
||||
#include "utlbuffer.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include <KeyValues.h>
|
||||
#include "MultipleRequest.h"
|
||||
|
||||
bool SceneManager_HasWindowStyle( mxWindow *w, int bits )
|
||||
{
|
||||
HWND wnd = (HWND)w->getHandle();
|
||||
DWORD style = GetWindowLong( wnd, GWL_STYLE );
|
||||
return ( style & bits ) ? true : false;
|
||||
}
|
||||
|
||||
bool SceneManager_HasWindowExStyle( mxWindow *w, int bits )
|
||||
{
|
||||
HWND wnd = (HWND)w->getHandle();
|
||||
DWORD style = GetWindowLong( wnd, GWL_EXSTYLE );
|
||||
return ( style & bits ) ? true : false;
|
||||
}
|
||||
|
||||
void SceneManager_AddWindowStyle( mxWindow *w, int addbits )
|
||||
{
|
||||
HWND wnd = (HWND)w->getHandle();
|
||||
DWORD style = GetWindowLong( wnd, GWL_STYLE );
|
||||
style |= addbits;
|
||||
SetWindowLong( wnd, GWL_STYLE, style );
|
||||
}
|
||||
|
||||
void SceneManager_AddWindowExStyle( mxWindow *w, int addbits )
|
||||
{
|
||||
HWND wnd = (HWND)w->getHandle();
|
||||
DWORD style = GetWindowLong( wnd, GWL_EXSTYLE );
|
||||
style |= addbits;
|
||||
SetWindowLong( wnd, GWL_EXSTYLE, style );
|
||||
}
|
||||
|
||||
void SceneManager_RemoveWindowStyle( mxWindow *w, int removebits )
|
||||
{
|
||||
HWND wnd = (HWND)w->getHandle();
|
||||
DWORD style = GetWindowLong( wnd, GWL_STYLE );
|
||||
style &= ~removebits;
|
||||
SetWindowLong( wnd, GWL_STYLE, style );
|
||||
}
|
||||
|
||||
void SceneManager_RemoveWindowExStyle( mxWindow *w, int removebits )
|
||||
{
|
||||
HWND wnd = (HWND)w->getHandle();
|
||||
DWORD style = GetWindowLong( wnd, GWL_EXSTYLE );
|
||||
style &= ~removebits;
|
||||
SetWindowLong( wnd, GWL_EXSTYLE, style );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *w -
|
||||
//-----------------------------------------------------------------------------
|
||||
void SceneManager_MakeToolWindow( mxWindow *w, bool smallcaption )
|
||||
{
|
||||
SceneManager_AddWindowStyle( w, WS_VISIBLE | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS );
|
||||
|
||||
if ( smallcaption )
|
||||
{
|
||||
SceneManager_AddWindowExStyle( w, WS_EX_OVERLAPPEDWINDOW );
|
||||
SceneManager_AddWindowExStyle( w, WS_EX_TOOLWINDOW );
|
||||
}
|
||||
else
|
||||
{
|
||||
SceneManager_RemoveWindowStyle( w, WS_SYSMENU );
|
||||
}
|
||||
}
|
||||
|
||||
char *va( const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
static char output[4][1024];
|
||||
static int outbuffer = 0;
|
||||
|
||||
outbuffer++;
|
||||
va_start( args, fmt );
|
||||
vprintf( fmt, args );
|
||||
vsprintf( output[ outbuffer & 3 ], fmt, args );
|
||||
return output[ outbuffer & 3 ];
|
||||
}
|
||||
|
||||
void Con_Overprintf( const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
static char output[1024];
|
||||
|
||||
va_start( args, fmt );
|
||||
vprintf( fmt, args );
|
||||
vsprintf( output, fmt, args );
|
||||
|
||||
if ( !g_pStatusWindow )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_pStatusWindow->StatusPrint( CONSOLE_R, CONSOLE_G, CONSOLE_B, true, output );
|
||||
}
|
||||
|
||||
void Con_Printf( const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
static char output[1024];
|
||||
|
||||
va_start( args, fmt );
|
||||
// vprintf( fmt, args );
|
||||
vsprintf( output, fmt, args );
|
||||
va_end( args );
|
||||
|
||||
if ( !g_pStatusWindow )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_pStatusWindow->StatusPrint( CONSOLE_R, CONSOLE_G, CONSOLE_B, false, output );
|
||||
}
|
||||
|
||||
void Con_ColorPrintf( int r, int g, int b, const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
static char output[1024];
|
||||
|
||||
va_start( args, fmt );
|
||||
vprintf( fmt, args );
|
||||
vsprintf( output, fmt, args );
|
||||
|
||||
if ( !g_pStatusWindow )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_pStatusWindow->StatusPrint( r, g, b, false, output );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pname -
|
||||
// Output : char
|
||||
//-----------------------------------------------------------------------------
|
||||
char *SceneManager_MakeWindowsSlashes( char *pname )
|
||||
{
|
||||
static char returnString[ 4096 ];
|
||||
strcpy( returnString, pname );
|
||||
pname = returnString;
|
||||
|
||||
while ( *pname ) {
|
||||
if ( *pname == '/' )
|
||||
*pname = '\\';
|
||||
pname++;
|
||||
}
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : const char
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *SceneManager_GetGameDirectory( void )
|
||||
{
|
||||
// Todo: Make SceneManager only use the filesystem read/write paths.
|
||||
return gamedir;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Takes a full path and determines if the file exists on the disk
|
||||
// Input : *filename -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SceneManager_FullpathFileExists( const char *filename )
|
||||
{
|
||||
// Should be a full path
|
||||
Assert( strchr( filename, ':' ) );
|
||||
|
||||
struct _stat buf;
|
||||
int result = _stat( filename, &buf );
|
||||
if ( result != -1 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: converts an english string to unicode
|
||||
//-----------------------------------------------------------------------------
|
||||
int ConvertANSIToUnicode(const char *ansi, wchar_t *unicode, int unicodeBufferSize)
|
||||
{
|
||||
return ::MultiByteToWideChar(CP_ACP, 0, ansi, -1, unicode, unicodeBufferSize);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: converts an unicode string to an english string
|
||||
//-----------------------------------------------------------------------------
|
||||
int ConvertUnicodeToANSI(const wchar_t *unicode, char *ansi, int ansiBufferSize)
|
||||
{
|
||||
return ::WideCharToMultiByte(CP_ACP, 0, unicode, -1, ansi, ansiBufferSize, NULL, NULL);
|
||||
}
|
||||
|
||||
int Sys_Exec( const char *pProgName, const char *pCmdLine, bool verbose )
|
||||
{
|
||||
#if 0
|
||||
int count = 0;
|
||||
char cmdLine[1024];
|
||||
STARTUPINFO si;
|
||||
|
||||
memset( &si, 0, sizeof(si) );
|
||||
si.cb = sizeof(si);
|
||||
//GetStartupInfo( &si );
|
||||
|
||||
sprintf( cmdLine, "%s %s", pProgName, pCmdLine );
|
||||
|
||||
PROCESS_INFORMATION pi;
|
||||
memset( &pi, 0, sizeof( pi ) );
|
||||
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
|
||||
if ( CreateProcess( NULL, cmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi ) )
|
||||
{
|
||||
WaitForSingleObject( pi.hProcess, INFINITE );
|
||||
/*
|
||||
do
|
||||
{
|
||||
WaitForInputIdle( pi.hProcess, 100 );
|
||||
count++;
|
||||
} while ( count < 100 );
|
||||
*/
|
||||
|
||||
/*
|
||||
DWORD exitCode = STILL_ACTIVE;
|
||||
do
|
||||
{
|
||||
BOOL ok = GetExitCodeProcess( pi.hProcess, &exitCode );
|
||||
if ( !ok )
|
||||
break;
|
||||
Sleep( 100 );
|
||||
} while ( exitCode == STILL_ACTIVE );
|
||||
*/
|
||||
|
||||
DWORD exitCode;
|
||||
|
||||
GetExitCodeProcess( pi.hProcess, &exitCode );
|
||||
|
||||
Con_Printf( "Finished\n" );
|
||||
|
||||
CloseHandle( pi.hProcess );
|
||||
return (int)exitCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *lpMsgBuf;
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
||||
Con_Printf( "error %s\n", lpMsgBuf );
|
||||
|
||||
LocalFree( (HLOCAL)lpMsgBuf );
|
||||
}
|
||||
|
||||
return false;
|
||||
#else
|
||||
char tmp[1024];
|
||||
sprintf( tmp, "%s %s\n", pProgName, pCmdLine );
|
||||
|
||||
_strlwr( tmp );
|
||||
|
||||
int iret = system( tmp );
|
||||
if ( iret != 0 && verbose )
|
||||
{
|
||||
Con_Printf( "Execution failed: %s\n", tmp );
|
||||
}
|
||||
|
||||
return iret;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Checks it out/ checks it in baby
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void SceneManager_VSSCheckout( char const *pUserName, char const *pProjectDir,
|
||||
char const* pRelativeDir, char const* pDestPath, char const* pFileNameWithExtension )
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
// Check for the existence of the file in source safe...
|
||||
sprintf( buf, "filetype %s/%s%s -O- -y%s\n",
|
||||
pProjectDir, pRelativeDir, pFileNameWithExtension,
|
||||
pUserName );
|
||||
int retVal = Sys_Exec( "ss.exe", buf, false );
|
||||
if (retVal != 0 )
|
||||
{
|
||||
Con_Printf( "File %s missing from VSS\n", pFileNameWithExtension );
|
||||
return;
|
||||
}
|
||||
|
||||
// It's there, try to check it out
|
||||
sprintf( buf, "checkout %s/%s%s -GL%s -GWA -O- -y%s\n",
|
||||
pProjectDir, pRelativeDir, pFileNameWithExtension,
|
||||
pDestPath, pUserName );
|
||||
Sys_Exec( "ss.exe", buf, true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Checks it out/ checks it in baby
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void SceneManager_VSSCheckin( char const *pUserName, char const *pProjectDir,
|
||||
char const* pRelativeDir, char const* pDestPath, char const* pFileNameWithExtension )
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
// Check for the existence of the file on disk. If it's not there, don't bother
|
||||
sprintf( buf, "%s%s", pDestPath, pFileNameWithExtension );
|
||||
struct _stat statbuf;
|
||||
int result = _stat( buf, &statbuf );
|
||||
if (result != 0)
|
||||
return;
|
||||
|
||||
// Check for the existence of the file in source safe...
|
||||
sprintf( buf, "filetype %s/%s%s -O- -y%s\n",
|
||||
pProjectDir, pRelativeDir, pFileNameWithExtension,
|
||||
pUserName );
|
||||
int retVal = Sys_Exec( "ss.exe", buf, false );
|
||||
if (retVal != 0)
|
||||
{
|
||||
sprintf( buf, "Cp %s -O- -y%s\n",
|
||||
pProjectDir ,
|
||||
pUserName );
|
||||
Sys_Exec( "ss.exe", buf, true );
|
||||
|
||||
// Try to add the file to source safe...
|
||||
sprintf( buf, "add %s%s -GL%s -O- -I- -y%s\n",
|
||||
pRelativeDir, pFileNameWithExtension,
|
||||
pDestPath, pUserName );
|
||||
Sys_Exec( "ss.exe", buf, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's there, just check it in
|
||||
sprintf( buf, "checkin %s/%s%s -GL%s -O- -I- -y%s\n",
|
||||
pProjectDir, pRelativeDir, pFileNameWithExtension,
|
||||
pDestPath, pUserName );
|
||||
Sys_Exec( "ss.exe", buf, true );
|
||||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
void VSS_Checkout( char const *name, bool updatestaticons /*= true*/ )
|
||||
{
|
||||
CWorkspace *ws = GetWorkspaceManager()->GetBrowser()->GetWorkspace();
|
||||
if ( !ws )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( filesystem->IsFileWritable( name ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char path[ 256 ];
|
||||
char filename[ 256 ];
|
||||
|
||||
SplitFileName( name, path, sizeof( path ), filename, sizeof( filename ) );
|
||||
|
||||
Con_ColorPrintf( 200, 200, 100, "VSS Checkout: '%s'\n", name );
|
||||
|
||||
SceneManager_VSSCheckout(
|
||||
ws->GetVSSUserName(),
|
||||
ws->GetVSSProject(),
|
||||
path,
|
||||
va( "%s%s", gamedir, path ),
|
||||
filename );
|
||||
|
||||
if ( updatestaticons )
|
||||
{
|
||||
GetWorkspaceManager()->RefreshBrowsers();
|
||||
}
|
||||
}
|
||||
|
||||
void VSS_Checkin( char const *name, bool updatestaticons /*= true*/ )
|
||||
{
|
||||
CWorkspace *ws = GetWorkspaceManager()->GetBrowser()->GetWorkspace();
|
||||
if ( !ws )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !filesystem->IsFileWritable( name ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char path[ 256 ];
|
||||
char filename[ 256 ];
|
||||
|
||||
SplitFileName( name, path, sizeof( path ), filename, sizeof( filename ) );
|
||||
|
||||
Con_ColorPrintf( 200, 200, 100, "VSS Checkin: '%s'\n", name );
|
||||
|
||||
SceneManager_VSSCheckin(
|
||||
ws->GetVSSUserName(),
|
||||
ws->GetVSSProject(),
|
||||
path,
|
||||
va( "%s%s", gamedir, path ),
|
||||
filename );
|
||||
|
||||
if ( updatestaticons )
|
||||
{
|
||||
GetWorkspaceManager()->RefreshBrowsers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Implements the RIFF i/o interface on stdio
|
||||
//-----------------------------------------------------------------------------
|
||||
class StdIOReadBinary : public IFileReadBinary
|
||||
{
|
||||
public:
|
||||
int open( const char *pFileName )
|
||||
{
|
||||
return (int)filesystem->Open( pFileName, "rb" );
|
||||
}
|
||||
|
||||
int read( void *pOutput, int size, int file )
|
||||
{
|
||||
if ( !file )
|
||||
return 0;
|
||||
|
||||
return filesystem->Read( pOutput, size, (FileHandle_t)file );
|
||||
}
|
||||
|
||||
void seek( int file, int pos )
|
||||
{
|
||||
if ( !file )
|
||||
return;
|
||||
|
||||
filesystem->Seek( (FileHandle_t)file, pos, FILESYSTEM_SEEK_HEAD );
|
||||
}
|
||||
|
||||
unsigned int tell( int file )
|
||||
{
|
||||
if ( !file )
|
||||
return 0;
|
||||
|
||||
return filesystem->Tell( (FileHandle_t)file );
|
||||
}
|
||||
|
||||
unsigned int size( int file )
|
||||
{
|
||||
if ( !file )
|
||||
return 0;
|
||||
|
||||
return filesystem->Size( (FileHandle_t)file );
|
||||
}
|
||||
|
||||
void close( int file )
|
||||
{
|
||||
if ( !file )
|
||||
return;
|
||||
|
||||
filesystem->Close( (FileHandle_t)file );
|
||||
}
|
||||
};
|
||||
|
||||
class StdIOWriteBinary : public IFileWriteBinary
|
||||
{
|
||||
public:
|
||||
int create( const char *pFileName )
|
||||
{
|
||||
return (int)filesystem->Open( pFileName, "wb" );
|
||||
}
|
||||
|
||||
int write( void *pData, int size, int file )
|
||||
{
|
||||
return filesystem->Write( pData, size, (FileHandle_t)file );
|
||||
}
|
||||
|
||||
void close( int file )
|
||||
{
|
||||
filesystem->Close( (FileHandle_t)file );
|
||||
}
|
||||
|
||||
void seek( int file, int pos )
|
||||
{
|
||||
filesystem->Seek( (FileHandle_t)file, pos, FILESYSTEM_SEEK_HEAD );
|
||||
}
|
||||
|
||||
unsigned int tell( int file )
|
||||
{
|
||||
return filesystem->Tell( (FileHandle_t)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 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : store -
|
||||
//-----------------------------------------------------------------------------
|
||||
static void SceneManager_StoreValveDataChunk( CSentence& sentence, IterateOutputRIFF& store )
|
||||
{
|
||||
// Buffer and dump data
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
|
||||
sentence.SaveToBuffer( buf );
|
||||
|
||||
// Copy into store
|
||||
store.ChunkWriteData( buf.Base(), buf.TellPut() );
|
||||
}
|
||||
|
||||
bool SceneManager_SaveSentenceToWavFile( char const *wavfile, CSentence& sentence )
|
||||
{
|
||||
char tempfile[ 512 ];
|
||||
|
||||
Q_StripExtension( wavfile, tempfile, sizeof( tempfile ) );
|
||||
Q_DefaultExtension( tempfile, ".tmp", sizeof( tempfile ) );
|
||||
|
||||
if ( filesystem->FileExists( tempfile, "GAME" ) )
|
||||
{
|
||||
filesystem->RemoveFile( tempfile, "GAME" );
|
||||
}
|
||||
|
||||
if ( !filesystem->IsFileWritable( wavfile ) )
|
||||
{
|
||||
int retval = MultipleRequest( va( "Check out '%s'?", wavfile ) );
|
||||
if ( retval != 0 )
|
||||
return false;
|
||||
|
||||
VSS_Checkout( wavfile );
|
||||
}
|
||||
|
||||
if ( !filesystem->IsFileWritable( wavfile ) )
|
||||
{
|
||||
Con_Printf( "%s is not writable, can't save sentence data to file\n", wavfile );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rename original wavfile to temp
|
||||
filesystem->RenameFile( wavfile, tempfile, "GAME" );
|
||||
|
||||
// NOTE: Put this in it's own scope so that the destructor for outfileRFF actually closes the file!!!!
|
||||
{
|
||||
// Read from Temp
|
||||
InFileRIFF riff( tempfile, io_in );
|
||||
Assert( riff.RIFFName() == RIFF_WAVE );
|
||||
|
||||
// set up the iterator for the whole file (root RIFF is a chunk)
|
||||
IterateRIFF walk( riff, riff.RIFFSize() );
|
||||
|
||||
// And put data back into original wavfile by name
|
||||
OutFileRIFF riffout( wavfile, io_out );
|
||||
|
||||
IterateOutputRIFF store( riffout );
|
||||
|
||||
bool wordtrackwritten = false;
|
||||
|
||||
// Walk input chunks and copy to output
|
||||
while ( walk.ChunkAvailable() )
|
||||
{
|
||||
store.ChunkStart( walk.ChunkName() );
|
||||
|
||||
switch ( walk.ChunkName() )
|
||||
{
|
||||
case WAVE_VALVEDATA:
|
||||
{
|
||||
// Overwrite data
|
||||
SceneManager_StoreValveDataChunk( sentence, store );
|
||||
wordtrackwritten = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
store.CopyChunkData( walk );
|
||||
break;
|
||||
}
|
||||
|
||||
store.ChunkFinish();
|
||||
|
||||
walk.ChunkNext();
|
||||
}
|
||||
|
||||
// If we didn't write it above, write it now
|
||||
if ( !wordtrackwritten )
|
||||
{
|
||||
store.ChunkStart( WAVE_VALVEDATA );
|
||||
SceneManager_StoreValveDataChunk( sentence, store );
|
||||
store.ChunkFinish();
|
||||
}
|
||||
}
|
||||
|
||||
// Remove temp file
|
||||
filesystem->RemoveFile( tempfile, NULL );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SceneManager_LoadWindowPositions( KeyValues *kv, mxWindow *wnd )
|
||||
{
|
||||
bool zoomed = kv->GetInt( "zoomed", 0 ) ? true : false;
|
||||
int x = kv->GetInt( "x", 0 );
|
||||
int y = kv->GetInt( "y", 0 );
|
||||
int w = kv->GetInt( "w", 400 );
|
||||
int h = kv->GetInt( "h", 300 );
|
||||
|
||||
wnd->setBounds( x, y, w, h );
|
||||
if ( zoomed )
|
||||
{
|
||||
ShowWindow( (HWND)wnd->getHandle(), SW_SHOWMAXIMIZED );
|
||||
}
|
||||
}
|
||||
|
||||
static void Indent( CUtlBuffer& buf, int numtabs )
|
||||
{
|
||||
for ( int i = 0 ; i < numtabs; i++ )
|
||||
{
|
||||
buf.Printf( "\t" );
|
||||
}
|
||||
}
|
||||
|
||||
void SceneManager_SaveWindowPositions( CUtlBuffer& buf, int indent, mxWindow *wnd )
|
||||
{
|
||||
int x, y, w, h;
|
||||
|
||||
x = wnd->x();
|
||||
y = wnd->y();
|
||||
w = wnd->w();
|
||||
h = wnd->h();
|
||||
|
||||
// xpos and ypos are screen space
|
||||
POINT pt;
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
|
||||
// Convert from screen space to relative to client area of parent window so
|
||||
// the setBounds == MoveWindow call will offset to the same location
|
||||
if ( wnd->getParent() )
|
||||
{
|
||||
ScreenToClient( (HWND)wnd->getParent()->getHandle(), &pt );
|
||||
x = (short)pt.x;
|
||||
y = (short)pt.y;
|
||||
}
|
||||
|
||||
|
||||
Indent( buf, indent );
|
||||
buf.Printf( "\"x\"\t\"%i\"\n", x );
|
||||
|
||||
Indent( buf, indent );
|
||||
buf.Printf( "\"y\"\t\"%i\"\n", y );
|
||||
|
||||
Indent( buf, indent );
|
||||
buf.Printf( "\"w\"\t\"%i\"\n", w );
|
||||
|
||||
Indent( buf, indent );
|
||||
buf.Printf( "\"h\"\t\"%i\"\n", h );
|
||||
|
||||
bool zoomed = IsZoomed( (HWND)wnd->getHandle() ) ? true : false;
|
||||
|
||||
Indent( buf, indent );
|
||||
buf.Printf( "\"zoomed\"\t\"%i\"\n", zoomed ? 1 : 0 );
|
||||
|
||||
}
|
||||
#if defined( _WIN32 ) || defined( WIN32 )
|
||||
#define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/')
|
||||
#else //_WIN32
|
||||
#define PATHSEPARATOR(c) ((c) == '/')
|
||||
#endif //_WIN32
|
||||
|
||||
static bool charsmatch( char c1, char c2 )
|
||||
{
|
||||
if ( tolower( c1 ) == tolower( c2 ) )
|
||||
return true;
|
||||
if ( PATHSEPARATOR( c1 ) && PATHSEPARATOR( c2 ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
char *Q_stristr_slash( char const *pStr, char const *pSearch )
|
||||
{
|
||||
AssertValidStringPtr(pStr);
|
||||
AssertValidStringPtr(pSearch);
|
||||
|
||||
if (!pStr || !pSearch)
|
||||
return 0;
|
||||
|
||||
char const* pLetter = pStr;
|
||||
|
||||
// Check the entire string
|
||||
while (*pLetter != 0)
|
||||
{
|
||||
// Skip over non-matches
|
||||
if ( charsmatch( *pLetter, *pSearch ) )
|
||||
{
|
||||
// Check for match
|
||||
char const* pMatch = pLetter + 1;
|
||||
char const* pTest = pSearch + 1;
|
||||
while (*pTest != 0)
|
||||
{
|
||||
// We've run off the end; don't bother.
|
||||
if (*pMatch == 0)
|
||||
return 0;
|
||||
|
||||
if ( !charsmatch( *pMatch, *pTest ) )
|
||||
break;
|
||||
|
||||
++pMatch;
|
||||
++pTest;
|
||||
}
|
||||
|
||||
// Found a match!
|
||||
if (*pTest == 0)
|
||||
return (char *)pLetter;
|
||||
}
|
||||
|
||||
++pLetter;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *filename -
|
||||
//-----------------------------------------------------------------------------
|
||||
void MakeFileWriteable( const char *filename )
|
||||
{
|
||||
Assert( filesystem );
|
||||
char fullpath[ 512 ];
|
||||
if (filesystem->GetLocalPath( filename, fullpath, sizeof(fullpath) ))
|
||||
{
|
||||
Q_FixSlashes( fullpath );
|
||||
SetFileAttributes( fullpath, FILE_ATTRIBUTE_NORMAL );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SCENEMANAGER_TOOLS_H
|
||||
#define SCENEMANAGER_TOOLS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class mxWindow;
|
||||
class ITreeItem;
|
||||
|
||||
#define ERROR_R 255
|
||||
#define ERROR_G 102
|
||||
#define ERROR_B 0
|
||||
|
||||
#define CONSOLE_R 82
|
||||
#define CONSOLE_G 173
|
||||
#define CONSOLE_B 216
|
||||
|
||||
class CSentence;
|
||||
class KeyValues;
|
||||
class CUtlBuffer;
|
||||
|
||||
bool SceneManager_LoadSentenceFromWavFile( char const *wavfile, CSentence& sentence );
|
||||
bool SceneManager_SaveSentenceToWavFile( char const *wavfile, CSentence& sentence );
|
||||
|
||||
void SceneManager_AddWindowStyle( mxWindow *w, int addbits );
|
||||
void SceneManager_MakeToolWindow( mxWindow *w, bool smallcaption );
|
||||
|
||||
char *va( PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
void Con_Printf( PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
void Con_Overprintf( PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
void Con_ColorPrintf( int r, int g, int b, PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
|
||||
char *SceneManager_MakeWindowsSlashes( char *pname );
|
||||
const char *SceneManager_GetGameDirectory( void );
|
||||
bool SceneManager_FullpathFileExists( const char *filename );
|
||||
|
||||
int ConvertANSIToUnicode(const char *ansi, wchar_t *unicode, int unicodeBufferSize);
|
||||
int ConvertUnicodeToANSI(const wchar_t *unicode, char *ansi, int ansiBufferSize);
|
||||
|
||||
extern class IFileSystem *filesystem;
|
||||
|
||||
extern char g_appTitle[];
|
||||
|
||||
void VSS_Checkout( char const *name, bool updatestaticons = true );
|
||||
void VSS_Checkin( char const *name, bool updatestaticons = true );
|
||||
|
||||
void SceneManager_LoadWindowPositions( KeyValues *kv, mxWindow *wnd );
|
||||
void SceneManager_SaveWindowPositions( CUtlBuffer& buf, int indent, mxWindow *wnd );
|
||||
|
||||
void MakeFileWriteable( const char *filename );
|
||||
|
||||
#endif // SCENEMANAGER_TOOLS_H
|
||||
@@ -0,0 +1,56 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include <stdio.h>
|
||||
#include "snd_audio_source.h"
|
||||
#include "iscenemanagersound.h"
|
||||
|
||||
extern CAudioSource *Audio_CreateMemoryWave( const char *pName );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Simple wrapper to crack naming convention and create the proper wave source
|
||||
// Input : *pName - WAVE filename
|
||||
// Output : CAudioSource
|
||||
//-----------------------------------------------------------------------------
|
||||
CAudioSource *AudioSource_Create( const char *pName )
|
||||
{
|
||||
if ( !pName )
|
||||
return NULL;
|
||||
|
||||
// if ( pName[0] == '!' ) // sentence
|
||||
;
|
||||
|
||||
// Names that begin with "*" are streaming.
|
||||
// Skip over the * and create a streamed source
|
||||
if ( pName[0] == '*' )
|
||||
{
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// These are loaded into memory directly
|
||||
return Audio_CreateMemoryWave( pName );
|
||||
}
|
||||
|
||||
CAudioSource::~CAudioSource( void )
|
||||
{
|
||||
CAudioMixer *mixer;
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
mixer = sound->FindMixer( this );
|
||||
if ( !mixer )
|
||||
break;
|
||||
|
||||
sound->StopSound( mixer );
|
||||
}
|
||||
}
|
||||
|
||||
CAudioSource::CAudioSource( void )
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SND_AUDIO_SOURCE_H
|
||||
#define SND_AUDIO_SOURCE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
// fixed point stuff for real-time resampling
|
||||
#define FIX_BITS 28
|
||||
#define FIX_SCALE (1 << FIX_BITS)
|
||||
#define FIX_MASK ((1 << FIX_BITS)-1)
|
||||
#define FIX_FLOAT(a) ((int)((a) * FIX_SCALE))
|
||||
#define FIX(a) (((int)(a)) << FIX_BITS)
|
||||
#define FIX_INTPART(a) (((int)(a)) >> FIX_BITS)
|
||||
#define FIX_FRACTION(a,b) (FIX(a)/(b))
|
||||
#define FIX_FRACPART(a) ((a) & FIX_MASK)
|
||||
|
||||
typedef unsigned int fixedint;
|
||||
|
||||
typedef struct channel_s channel_t;
|
||||
|
||||
class CAudioSource;
|
||||
|
||||
class IAudioDevice
|
||||
{
|
||||
public:
|
||||
// Add a virtual destructor to silence the clang warning.
|
||||
// This is harmless but not important since the only derived class
|
||||
// doesn't have a destructor.
|
||||
virtual ~IAudioDevice() {}
|
||||
|
||||
virtual void MixBegin( void ) = 0;
|
||||
virtual void Mix8Mono( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward = true ) = 0;
|
||||
virtual void Mix8Stereo( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward = true ) = 0;
|
||||
virtual void Mix16Mono( channel_t *pChannel, short *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward = true ) = 0;
|
||||
virtual void Mix16Stereo( channel_t *pChannel, short *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward = true ) = 0;
|
||||
virtual int MaxSampleCount( void ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is an instance of an audio source.
|
||||
// Mixers are attached to channels and reference an audio source.
|
||||
// Mixers are specific to the sample format and source format.
|
||||
// Mixers are never re-used, so they can track instance data like
|
||||
// sample position, fractional sample, stream cache, faders, etc.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAudioMixer
|
||||
{
|
||||
public:
|
||||
virtual ~CAudioMixer( void ) {}
|
||||
|
||||
// UNDONE: time compress
|
||||
virtual bool MixDataToDevice( IAudioDevice *pDevice, channel_t *pChannel, int startSample, int sampleCount, int outputRate, bool forward = true ) = 0;
|
||||
virtual void IncrementSamples( channel_t *pChannel, int startSample, int sampleCount,int outputRate, bool forward = true ) = 0;
|
||||
virtual bool SkipSamples( channel_t *pChannel, int startSample, int sampleCount, int outputRate, bool forward = true ) = 0;
|
||||
|
||||
virtual CAudioSource *GetSource( void ) = 0;
|
||||
|
||||
virtual int GetSamplePosition( void ) = 0;
|
||||
|
||||
virtual bool SetSamplePosition( int position ) = 0;
|
||||
virtual void SetLoopPosition( int position ) = 0;
|
||||
virtual int GetStartPosition( void ) = 0;
|
||||
|
||||
virtual bool GetActive( void ) = 0;
|
||||
virtual void SetActive( bool active ) = 0;
|
||||
|
||||
virtual void SetModelIndex( int index ) = 0;
|
||||
virtual int GetModelIndex( void ) const = 0;
|
||||
|
||||
virtual void SetDirection( bool forward ) = 0;
|
||||
virtual bool GetDirection( void ) const = 0;
|
||||
|
||||
virtual void SetAutoDelete( bool autodelete ) = 0;
|
||||
virtual bool GetAutoDelete( void ) const = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A source is an abstraction for a stream, cached file, or procedural
|
||||
// source of audio.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSentence;
|
||||
|
||||
class CAudioSource
|
||||
{
|
||||
public:
|
||||
CAudioSource( void );
|
||||
virtual ~CAudioSource( void );
|
||||
|
||||
// Create an instance (mixer) of this audio source
|
||||
virtual CAudioMixer *CreateMixer( void ) = 0;
|
||||
virtual int GetOutputData( void **pData, int samplePosition, int sampleCount, bool forward = true ) = 0;
|
||||
virtual int SampleRate( void ) = 0;
|
||||
virtual int SampleSize( void ) = 0;
|
||||
virtual int SampleCount( void ) = 0;
|
||||
virtual float TrueSampleSize( void ) = 0;
|
||||
virtual bool IsLooped( void ) = 0;
|
||||
virtual bool IsStreaming( void ) = 0;
|
||||
virtual float GetRunningLength( void ) = 0;
|
||||
|
||||
virtual CSentence *GetSentence( void ) { return NULL; };
|
||||
|
||||
};
|
||||
|
||||
|
||||
extern CAudioSource *AudioSource_Create( const char *pName );
|
||||
|
||||
#endif // SND_AUDIO_SOURCE_H
|
||||
@@ -0,0 +1,492 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "snd_audio_source.h"
|
||||
#include "snd_wave_source.h"
|
||||
#include "snd_wave_mixer_private.h"
|
||||
#include "snd_wave_mixer_adpcm.h"
|
||||
#include "iscenemanagersound.h"
|
||||
#include "AudioWaveOutput.h"
|
||||
#include "tier2/riff.h"
|
||||
|
||||
typedef struct channel_s
|
||||
{
|
||||
int leftvol;
|
||||
int rightvol;
|
||||
int rleftvol;
|
||||
int rrightvol;
|
||||
float pitch;
|
||||
} channel_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// These mixers provide an abstraction layer between the audio device and
|
||||
// mixing/decoding code. They allow data to be decoded and mixed using
|
||||
// optimized, format sensitive code by calling back into the device that
|
||||
// controls them.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: maps mixing to 8-bit mono mixer
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAudioMixerWave8Mono : public CAudioMixerWave
|
||||
{
|
||||
public:
|
||||
CAudioMixerWave8Mono( CWaveData *data ) : CAudioMixerWave( data ) {}
|
||||
virtual void Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward = true )
|
||||
{
|
||||
pDevice->Mix8Mono( pChannel, (char *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: maps mixing to 8-bit stereo mixer
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAudioMixerWave8Stereo : public CAudioMixerWave
|
||||
{
|
||||
public:
|
||||
CAudioMixerWave8Stereo( CWaveData *data ) : CAudioMixerWave( data ) {}
|
||||
virtual void Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward = true )
|
||||
{
|
||||
pDevice->Mix8Stereo( pChannel, (char *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: maps mixing to 16-bit mono mixer
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAudioMixerWave16Mono : public CAudioMixerWave
|
||||
{
|
||||
public:
|
||||
CAudioMixerWave16Mono( CWaveData *data ) : CAudioMixerWave( data ) {}
|
||||
virtual void Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward = true )
|
||||
{
|
||||
pDevice->Mix16Mono( pChannel, (short *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: maps mixing to 16-bit stereo mixer
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAudioMixerWave16Stereo : public CAudioMixerWave
|
||||
{
|
||||
public:
|
||||
CAudioMixerWave16Stereo( CWaveData *data ) : CAudioMixerWave( data ) {}
|
||||
virtual void Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward = true )
|
||||
{
|
||||
pDevice->Mix16Stereo( pChannel, (short *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Create an approprite mixer type given the data format
|
||||
// Input : *data - data access abstraction
|
||||
// format - pcm or adpcm (1 or 2 -- RIFF format)
|
||||
// channels - number of audio channels (1 = mono, 2 = stereo)
|
||||
// bits - bits per sample
|
||||
// Output : CAudioMixer * abstract mixer type that maps mixing to appropriate code
|
||||
//-----------------------------------------------------------------------------
|
||||
CAudioMixer *CreateWaveMixer( CWaveData *data, int format, int channels, int bits )
|
||||
{
|
||||
if ( format == WAVE_FORMAT_PCM )
|
||||
{
|
||||
if ( channels > 1 )
|
||||
{
|
||||
if ( bits == 8 )
|
||||
return new CAudioMixerWave8Stereo( data );
|
||||
else
|
||||
return new CAudioMixerWave16Stereo( data );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bits == 8 )
|
||||
return new CAudioMixerWave8Mono( data );
|
||||
else
|
||||
return new CAudioMixerWave16Mono( data );
|
||||
}
|
||||
}
|
||||
else if ( format == WAVE_FORMAT_ADPCM )
|
||||
{
|
||||
return CreateADPCMMixer( data );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Init the base WAVE mixer.
|
||||
// Input : *data - data access object
|
||||
//-----------------------------------------------------------------------------
|
||||
CAudioMixerWave::CAudioMixerWave( CWaveData *data ) : m_pData(data)
|
||||
{
|
||||
m_loop = 0;
|
||||
m_sample = 0;
|
||||
m_absoluteSample = 0;
|
||||
m_fracOffset = 0;
|
||||
m_bActive = false;
|
||||
m_nModelIndex = -1;
|
||||
m_bForward = true;
|
||||
m_bAutoDelete = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Frees the data access object (we own it after construction)
|
||||
//-----------------------------------------------------------------------------
|
||||
CAudioMixerWave::~CAudioMixerWave( void )
|
||||
{
|
||||
delete m_pData;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Decode and read the data
|
||||
// by default we just pass the request on to the data access object
|
||||
// other mixers may need to buffer or decode the data for some reason
|
||||
//
|
||||
// Input : **pData - dest pointer
|
||||
// sampleCount - number of samples needed
|
||||
// Output : number of samples available in this batch
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAudioMixerWave::GetOutputData( void **pData, int samplePosition, int sampleCount, bool forward /*= true*/ )
|
||||
{
|
||||
if ( samplePosition != m_sample )
|
||||
{
|
||||
// Seek
|
||||
m_sample = samplePosition;
|
||||
m_absoluteSample = samplePosition;
|
||||
}
|
||||
|
||||
return m_pData->ReadSourceData( pData, m_sample, sampleCount, forward );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: calls through the wavedata to get the audio source
|
||||
// Output : CAudioSource
|
||||
//-----------------------------------------------------------------------------
|
||||
CAudioSource *CAudioMixerWave::GetSource( void )
|
||||
{
|
||||
if ( m_pData )
|
||||
return &m_pData->Source();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Gets the current sample location in playback
|
||||
// Output : int (samples from start of wave)
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAudioMixerWave::GetSamplePosition( void )
|
||||
{
|
||||
return m_sample;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : position -
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAudioMixerWave::SetSamplePosition( int position )
|
||||
{
|
||||
position = max( 0, position );
|
||||
|
||||
m_sample = position;
|
||||
m_absoluteSample = position;
|
||||
m_startpos = m_sample;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : position -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAudioMixerWave::SetLoopPosition( int position )
|
||||
{
|
||||
m_loop = position;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAudioMixerWave::GetStartPosition( void )
|
||||
{
|
||||
return m_startpos;
|
||||
}
|
||||
|
||||
bool CAudioMixerWave::GetActive( void )
|
||||
{
|
||||
return m_bActive;
|
||||
}
|
||||
|
||||
void CAudioMixerWave::SetActive( bool active )
|
||||
{
|
||||
m_bActive = active;
|
||||
}
|
||||
|
||||
void CAudioMixerWave::SetModelIndex( int index )
|
||||
{
|
||||
m_nModelIndex = index;
|
||||
}
|
||||
|
||||
int CAudioMixerWave::GetModelIndex( void ) const
|
||||
{
|
||||
return m_nModelIndex;
|
||||
}
|
||||
|
||||
void CAudioMixerWave::SetDirection( bool forward )
|
||||
{
|
||||
m_bForward = forward;
|
||||
}
|
||||
|
||||
bool CAudioMixerWave::GetDirection( void ) const
|
||||
{
|
||||
return m_bForward;
|
||||
}
|
||||
|
||||
void CAudioMixerWave::SetAutoDelete( bool autodelete )
|
||||
{
|
||||
m_bAutoDelete = autodelete;
|
||||
}
|
||||
|
||||
bool CAudioMixerWave::GetAutoDelete( void ) const
|
||||
{
|
||||
return m_bAutoDelete;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pChannel -
|
||||
// sampleCount -
|
||||
// outputRate -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAudioMixerWave::IncrementSamples( channel_t *pChannel, int startSample, int sampleCount,int outputRate, bool forward /*= true*/ )
|
||||
{
|
||||
int inputSampleRate = (int)(pChannel->pitch * m_pData->Source().SampleRate());
|
||||
float rate = (float)inputSampleRate / outputRate;
|
||||
|
||||
int startpos = startSample;
|
||||
|
||||
if ( !forward )
|
||||
{
|
||||
int requestedstart = startSample - (int)( sampleCount * rate );
|
||||
if ( requestedstart < 0 )
|
||||
return;
|
||||
|
||||
startpos = max( 0, requestedstart );
|
||||
SetSamplePosition( startpos );
|
||||
}
|
||||
|
||||
while ( sampleCount > 0 )
|
||||
{
|
||||
int inputSampleCount;
|
||||
int outputSampleCount = sampleCount;
|
||||
|
||||
if ( outputRate != inputSampleRate )
|
||||
{
|
||||
inputSampleCount = (int)(sampleCount * rate);
|
||||
}
|
||||
else
|
||||
{
|
||||
inputSampleCount = sampleCount;
|
||||
}
|
||||
|
||||
sampleCount -= outputSampleCount;
|
||||
if ( forward )
|
||||
{
|
||||
m_sample += inputSampleCount;
|
||||
m_absoluteSample += inputSampleCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The device calls this to request data. The mixer must provide the
|
||||
// full amount of samples or have silence in its output stream.
|
||||
// Input : *pDevice - requesting device
|
||||
// sampleCount - number of samples at the output rate
|
||||
// outputRate - sampling rate of the request
|
||||
// Output : Returns true to keep mixing, false to delete this mixer
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAudioMixerWave::SkipSamples( channel_t *pChannel, int startSample, int sampleCount, int outputRate, bool forward /*= true*/ )
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
int inputSampleRate = (int)(pChannel->pitch * m_pData->Source().SampleRate());
|
||||
float rate = (float)inputSampleRate / outputRate;
|
||||
// fixedint fracstep = FIX_FLOAT( rate );
|
||||
|
||||
sampleCount = min( sampleCount, PAINTBUFFER_SIZE );
|
||||
|
||||
int startpos = startSample;
|
||||
|
||||
if ( !forward )
|
||||
{
|
||||
int requestedstart = startSample - (int)( sampleCount * rate );
|
||||
if ( requestedstart < 0 )
|
||||
return false;
|
||||
|
||||
startpos = max( 0, requestedstart );
|
||||
SetSamplePosition( startpos );
|
||||
}
|
||||
|
||||
while ( sampleCount > 0 )
|
||||
{
|
||||
int availableSamples;
|
||||
int inputSampleCount;
|
||||
char *pData = NULL;
|
||||
int outputSampleCount = sampleCount;
|
||||
|
||||
if ( outputRate != inputSampleRate )
|
||||
{
|
||||
inputSampleCount = (int)(sampleCount * rate);
|
||||
if ( !forward )
|
||||
{
|
||||
startSample = max( 0, startSample - inputSampleCount );
|
||||
}
|
||||
int availableSamples = GetOutputData( (void **)&pData, startSample, inputSampleCount, forward );
|
||||
if ( !availableSamples )
|
||||
break;
|
||||
|
||||
if ( availableSamples < inputSampleCount )
|
||||
{
|
||||
outputSampleCount = (int)(availableSamples / rate);
|
||||
inputSampleCount = availableSamples;
|
||||
}
|
||||
|
||||
// compute new fraction part of sample index
|
||||
float offset = (m_fracOffset / FIX_SCALE) + (rate * outputSampleCount);
|
||||
offset = offset - (float)((int)offset);
|
||||
m_fracOffset = FIX_FLOAT(offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !forward )
|
||||
{
|
||||
startSample = max( 0, startSample - sampleCount );
|
||||
}
|
||||
availableSamples = GetOutputData( (void **)&pData, startSample, sampleCount, forward );
|
||||
if ( !availableSamples )
|
||||
break;
|
||||
outputSampleCount = availableSamples;
|
||||
inputSampleCount = availableSamples;
|
||||
|
||||
}
|
||||
offset += outputSampleCount;
|
||||
sampleCount -= outputSampleCount;
|
||||
if ( forward )
|
||||
{
|
||||
m_sample += inputSampleCount;
|
||||
m_absoluteSample += inputSampleCount;
|
||||
}
|
||||
|
||||
if ( m_loop != 0 && m_sample >= m_loop )
|
||||
{
|
||||
SetSamplePosition( m_startpos );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( sampleCount > 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The device calls this to request data. The mixer must provide the
|
||||
// full amount of samples or have silence in its output stream.
|
||||
// Input : *pDevice - requesting device
|
||||
// sampleCount - number of samples at the output rate
|
||||
// outputRate - sampling rate of the request
|
||||
// Output : Returns true to keep mixing, false to delete this mixer
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAudioMixerWave::MixDataToDevice( IAudioDevice *pDevice, channel_t *pChannel, int startSample, int sampleCount, int outputRate, bool forward /*= true*/ )
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
int inputSampleRate = (int)(pChannel->pitch * m_pData->Source().SampleRate());
|
||||
float rate = (float)inputSampleRate / outputRate;
|
||||
fixedint fracstep = FIX_FLOAT( rate );
|
||||
|
||||
sampleCount = min( sampleCount, PAINTBUFFER_SIZE );
|
||||
|
||||
int startpos = startSample;
|
||||
|
||||
if ( !forward )
|
||||
{
|
||||
int requestedstart = startSample - (int)( sampleCount * rate );
|
||||
if ( requestedstart < 0 )
|
||||
return false;
|
||||
|
||||
startpos = max( 0, requestedstart );
|
||||
SetSamplePosition( startpos );
|
||||
}
|
||||
|
||||
while ( sampleCount > 0 )
|
||||
{
|
||||
int availableSamples;
|
||||
int inputSampleCount;
|
||||
char *pData = NULL;
|
||||
int outputSampleCount = sampleCount;
|
||||
|
||||
|
||||
if ( outputRate != inputSampleRate )
|
||||
{
|
||||
inputSampleCount = (int)(sampleCount * rate);
|
||||
|
||||
int availableSamples = GetOutputData( (void **)&pData, startpos, inputSampleCount, forward );
|
||||
if ( !availableSamples )
|
||||
break;
|
||||
|
||||
if ( availableSamples < inputSampleCount )
|
||||
{
|
||||
outputSampleCount = (int)(availableSamples / rate);
|
||||
inputSampleCount = availableSamples;
|
||||
}
|
||||
|
||||
Mix( pDevice, pChannel, pData, offset, m_fracOffset, fracstep, outputSampleCount, 0, forward );
|
||||
|
||||
// compute new fraction part of sample index
|
||||
float offset = (m_fracOffset / FIX_SCALE) + (rate * outputSampleCount);
|
||||
offset = offset - (float)((int)offset);
|
||||
m_fracOffset = FIX_FLOAT(offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
availableSamples = GetOutputData( (void **)&pData, startpos, sampleCount, forward );
|
||||
if ( !availableSamples )
|
||||
break;
|
||||
|
||||
outputSampleCount = availableSamples;
|
||||
inputSampleCount = availableSamples;
|
||||
|
||||
Mix( pDevice, pChannel, pData, offset, m_fracOffset, FIX(1), outputSampleCount, 0, forward );
|
||||
}
|
||||
offset += outputSampleCount;
|
||||
sampleCount -= outputSampleCount;
|
||||
|
||||
if ( forward )
|
||||
{
|
||||
m_sample += inputSampleCount;
|
||||
m_absoluteSample += inputSampleCount;
|
||||
}
|
||||
|
||||
if ( m_loop != 0 && m_sample >= m_loop )
|
||||
{
|
||||
SetSamplePosition( m_startpos );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( sampleCount > 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SND_WAVE_MIXER_H
|
||||
#define SND_WAVE_MIXER_H
|
||||
#pragma once
|
||||
|
||||
class CWaveData;
|
||||
class CAudioMixer;
|
||||
|
||||
CAudioMixer *CreateWaveMixer( CWaveData *data, int format, int channels, int bits );
|
||||
|
||||
|
||||
#endif // SND_WAVE_MIXER_H
|
||||
@@ -0,0 +1,511 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <mmreg.h>
|
||||
#include "snd_wave_source.h"
|
||||
#include "snd_wave_mixer_adpcm.h"
|
||||
#include "snd_wave_mixer_private.h"
|
||||
|
||||
// max size of ADPCM block in bytes
|
||||
#define MAX_BLOCK_SIZE 4096
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Mixer for ADPCM encoded audio
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAudioMixerWaveADPCM : public CAudioMixerWave
|
||||
{
|
||||
public:
|
||||
CAudioMixerWaveADPCM( CWaveData *data );
|
||||
~CAudioMixerWaveADPCM( void );
|
||||
|
||||
virtual void Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward = true );
|
||||
virtual int GetOutputData( void **pData, int samplePosition, int sampleCount, bool forward = true );
|
||||
|
||||
virtual bool SetSamplePosition( int position );
|
||||
|
||||
private:
|
||||
bool DecodeBlock( void );
|
||||
int NumChannels( void );
|
||||
void DecompressBlockMono( short *pOut, const char *pIn, int count );
|
||||
void DecompressBlockStereo( short *pOut, const char *pIn, int count );
|
||||
|
||||
void SetCurrentBlock( int block );
|
||||
int GetCurrentBlock( void ) const;
|
||||
int GetBlockNumberForSample( int samplePosition );
|
||||
bool IsSampleInCurrentBlock( int samplePosition );
|
||||
int GetFirstSampleForBlock( int blocknum ) const;
|
||||
|
||||
const ADPCMWAVEFORMAT *m_pFormat;
|
||||
const ADPCMCOEFSET *m_pCoefficients;
|
||||
|
||||
short *m_pSamples;
|
||||
int m_sampleCount;
|
||||
int m_samplePosition;
|
||||
|
||||
int m_blockSize;
|
||||
int m_offset;
|
||||
|
||||
int m_currentBlock;
|
||||
};
|
||||
|
||||
|
||||
CAudioMixerWaveADPCM::CAudioMixerWaveADPCM( CWaveData *data ) : CAudioMixerWave( data )
|
||||
{
|
||||
m_currentBlock = -1;
|
||||
m_pSamples = NULL;
|
||||
m_sampleCount = 0;
|
||||
m_samplePosition = 0;
|
||||
m_offset = 0;
|
||||
|
||||
m_pFormat = (const ADPCMWAVEFORMAT *)m_pData->Source().GetHeader();
|
||||
if ( m_pFormat )
|
||||
{
|
||||
m_pCoefficients = (ADPCMCOEFSET *)((char *)m_pFormat + sizeof(WAVEFORMATEX) + 4);
|
||||
|
||||
// create the decode buffer
|
||||
m_pSamples = new short[m_pFormat->wSamplesPerBlock * m_pFormat->wfx.nChannels];
|
||||
|
||||
// number of bytes for samples
|
||||
m_blockSize = ((m_pFormat->wSamplesPerBlock - 2) * m_pFormat->wfx.nChannels ) / 2;
|
||||
// size of channel header
|
||||
m_blockSize += 7 * m_pFormat->wfx.nChannels;
|
||||
// Assert(m_blockSize < MAX_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CAudioMixerWaveADPCM::~CAudioMixerWaveADPCM( void )
|
||||
{
|
||||
delete[] m_pSamples;
|
||||
}
|
||||
|
||||
|
||||
int CAudioMixerWaveADPCM::NumChannels( void )
|
||||
{
|
||||
if ( m_pFormat )
|
||||
{
|
||||
return m_pFormat->wfx.nChannels;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CAudioMixerWaveADPCM::Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward /*= true*/ )
|
||||
{
|
||||
if ( NumChannels() == 1 )
|
||||
pDevice->Mix16Mono( pChannel, (short *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
|
||||
else
|
||||
pDevice->Mix16Stereo( pChannel, (short *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
|
||||
}
|
||||
|
||||
|
||||
static int error_sign_lut[] = { 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1 };
|
||||
static int error_coefficients_lut[] = { 230, 230, 230, 230, 307, 409, 512, 614,
|
||||
768, 614, 512, 409, 307, 230, 230, 230 };
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: ADPCM decompress a single block of 1-channel audio
|
||||
// Input : *pOut - output buffer 16-bit
|
||||
// *pIn - input block
|
||||
// count - number of samples to decode (to support partial blocks)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAudioMixerWaveADPCM::DecompressBlockMono( short *pOut, const char *pIn, int count )
|
||||
{
|
||||
|
||||
int pred = *pIn++;
|
||||
int co1 = m_pCoefficients[pred].iCoef1;
|
||||
int co2 = m_pCoefficients[pred].iCoef2;
|
||||
|
||||
// read initial delta
|
||||
int delta = *((short *)pIn);
|
||||
pIn += 2;
|
||||
|
||||
// read initial samples for prediction
|
||||
int samp1 = *((short *)pIn);
|
||||
pIn += 2;
|
||||
|
||||
int samp2 = *((short *)pIn);
|
||||
pIn += 2;
|
||||
|
||||
// write out the initial samples (stored in reverse order)
|
||||
*pOut++ = (short)samp2;
|
||||
*pOut++ = (short)samp1;
|
||||
|
||||
// subtract the 2 samples in the header
|
||||
count -= 2;
|
||||
|
||||
// this is a toggle to read nibbles, first nibble is high
|
||||
int high = 1;
|
||||
|
||||
int error = 0, sample = 0;
|
||||
|
||||
// now process the block
|
||||
while ( count )
|
||||
{
|
||||
// read the error nibble from the input stream
|
||||
if ( high )
|
||||
{
|
||||
sample = (unsigned char) (*pIn++);
|
||||
// high nibble
|
||||
error = sample >> 4;
|
||||
// cache low nibble for next read
|
||||
sample = sample & 0xf;
|
||||
// Next read is from cache, not stream
|
||||
high = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// stored in previous read (low nibble)
|
||||
error = sample;
|
||||
// next read is from stream
|
||||
high = 1;
|
||||
}
|
||||
// convert to signed with LUT
|
||||
int errorSign = error_sign_lut[error];
|
||||
|
||||
// interpolate the new sample
|
||||
int predSample = (samp1 * co1) + (samp2 * co2);
|
||||
// coefficients are fixed point 8-bit, so shift back to 16-bit integer
|
||||
predSample >>= 8;
|
||||
|
||||
// Add in current error estimate
|
||||
predSample += (errorSign * delta);
|
||||
|
||||
// Correct error estimate
|
||||
delta = (delta * error_coefficients_lut[error]) >> 8;
|
||||
// Clamp error estimate
|
||||
if ( delta < 16 )
|
||||
delta = 16;
|
||||
|
||||
// clamp
|
||||
if ( predSample > 32767L )
|
||||
predSample = 32767L;
|
||||
else if ( predSample < -32768L )
|
||||
predSample = -32768L;
|
||||
|
||||
// output
|
||||
*pOut++ = (short)predSample;
|
||||
// move samples over
|
||||
samp2 = samp1;
|
||||
samp1 = predSample;
|
||||
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Decode a single block of stereo ADPCM audio
|
||||
// Input : *pOut - 16-bit output buffer
|
||||
// *pIn - ADPCM encoded block data
|
||||
// count - number of sample pairs to decode
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAudioMixerWaveADPCM::DecompressBlockStereo( short *pOut, const char *pIn, int count )
|
||||
{
|
||||
int pred[2], co1[2], co2[2];
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < 2; i++ )
|
||||
{
|
||||
pred[i] = *pIn++;
|
||||
co1[i] = m_pCoefficients[pred[i]].iCoef1;
|
||||
co2[i] = m_pCoefficients[pred[i]].iCoef2;
|
||||
}
|
||||
|
||||
int delta[2], samp1[2], samp2[2];
|
||||
|
||||
for ( i = 0; i < 2; i++, pIn += 2 )
|
||||
{
|
||||
// read initial delta
|
||||
delta[i] = *((short *)pIn);
|
||||
}
|
||||
|
||||
// read initial samples for prediction
|
||||
for ( i = 0; i < 2; i++, pIn += 2 )
|
||||
{
|
||||
samp1[i] = *((short *)pIn);
|
||||
}
|
||||
for ( i = 0; i < 2; i++, pIn += 2 )
|
||||
{
|
||||
samp2[i] = *((short *)pIn);
|
||||
}
|
||||
|
||||
// write out the initial samples (stored in reverse order)
|
||||
*pOut++ = (short)samp2[0]; // left
|
||||
*pOut++ = (short)samp2[1]; // right
|
||||
*pOut++ = (short)samp1[0]; // left
|
||||
*pOut++ = (short)samp1[1]; // right
|
||||
|
||||
// subtract the 2 samples in the header
|
||||
count -= 2;
|
||||
|
||||
// this is a toggle to read nibbles, first nibble is high
|
||||
int high = 1;
|
||||
|
||||
int error, sample = 0;
|
||||
|
||||
// now process the block
|
||||
while ( count )
|
||||
{
|
||||
for ( i = 0; i < 2; i++ )
|
||||
{
|
||||
// read the error nibble from the input stream
|
||||
if ( high )
|
||||
{
|
||||
sample = (unsigned char) (*pIn++);
|
||||
// high nibble
|
||||
error = sample >> 4;
|
||||
// cache low nibble for next read
|
||||
sample = sample & 0xf;
|
||||
// Next read is from cache, not stream
|
||||
high = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// stored in previous read (low nibble)
|
||||
error = sample;
|
||||
// next read is from stream
|
||||
high = 1;
|
||||
}
|
||||
// convert to signed with LUT
|
||||
int errorSign = error_sign_lut[error];
|
||||
|
||||
// interpolate the new sample
|
||||
int predSample = (samp1[i] * co1[i]) + (samp2[i] * co2[i]);
|
||||
// coefficients are fixed point 8-bit, so shift back to 16-bit integer
|
||||
predSample >>= 8;
|
||||
|
||||
// Add in current error estimate
|
||||
predSample += (errorSign * delta[i]);
|
||||
|
||||
// Correct error estimate
|
||||
delta[i] = (delta[i] * error_coefficients_lut[error]) >> 8;
|
||||
// Clamp error estimate
|
||||
if ( delta[i] < 16 )
|
||||
delta[i] = 16;
|
||||
|
||||
// clamp
|
||||
if ( predSample > 32767L )
|
||||
predSample = 32767L;
|
||||
else if ( predSample < -32768L )
|
||||
predSample = -32768L;
|
||||
|
||||
// output
|
||||
*pOut++ = (short)predSample;
|
||||
// move samples over
|
||||
samp2[i] = samp1[i];
|
||||
samp1[i] = predSample;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CAudioMixerWaveADPCM::DecodeBlock( void )
|
||||
{
|
||||
char tmpBlock[MAX_BLOCK_SIZE];
|
||||
char *pData;
|
||||
|
||||
int available = m_pData->ReadSourceData( (void **) (&pData), m_offset, m_blockSize );
|
||||
if ( available < m_blockSize )
|
||||
{
|
||||
int total = 0;
|
||||
while ( available && total < m_blockSize )
|
||||
{
|
||||
memcpy( tmpBlock + total, pData, available );
|
||||
total += available;
|
||||
available = m_pData->ReadSourceData( (void **) (&pData), m_offset + total, m_blockSize - total );
|
||||
}
|
||||
pData = tmpBlock;
|
||||
available = total;
|
||||
}
|
||||
|
||||
Assert( m_blockSize > 0 );
|
||||
|
||||
// Current block number is based on starting offset
|
||||
int blockNumber = m_offset / m_blockSize;
|
||||
SetCurrentBlock( blockNumber );
|
||||
|
||||
if ( !available )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// advance the file pointer
|
||||
m_offset += available;
|
||||
|
||||
int channelCount = NumChannels();
|
||||
|
||||
// this is sample pairs for stereo, samples for mono
|
||||
m_sampleCount = m_pFormat->wSamplesPerBlock;
|
||||
|
||||
// short block?, fixup sample count (2 samples per byte, divided by number of channels per sample set)
|
||||
m_sampleCount -= ((m_blockSize - available) * 2) / channelCount;
|
||||
|
||||
// new block, start at the first sample
|
||||
m_samplePosition = 0;
|
||||
|
||||
// no need to subclass for different channel counts...
|
||||
if ( channelCount == 1 )
|
||||
{
|
||||
DecompressBlockMono( m_pSamples, pData, m_sampleCount );
|
||||
}
|
||||
else
|
||||
{
|
||||
DecompressBlockStereo( m_pSamples, pData, m_sampleCount );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : block -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAudioMixerWaveADPCM::SetCurrentBlock( int block )
|
||||
{
|
||||
m_currentBlock = block;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAudioMixerWaveADPCM::GetCurrentBlock( void ) const
|
||||
{
|
||||
return m_currentBlock;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : samplePosition -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAudioMixerWaveADPCM::GetBlockNumberForSample( int samplePosition )
|
||||
{
|
||||
int blockNum = samplePosition / m_pFormat->wSamplesPerBlock;
|
||||
return blockNum;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : samplePosition -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAudioMixerWaveADPCM::IsSampleInCurrentBlock( int samplePosition )
|
||||
{
|
||||
int currentBlock = GetCurrentBlock();
|
||||
|
||||
int startSample = currentBlock * m_pFormat->wSamplesPerBlock;
|
||||
int endSample = startSample + m_pFormat->wSamplesPerBlock - 1;
|
||||
|
||||
if ( samplePosition >= startSample &&
|
||||
samplePosition <= endSample )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : blocknum -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAudioMixerWaveADPCM::GetFirstSampleForBlock( int blocknum ) const
|
||||
{
|
||||
return m_pFormat->wSamplesPerBlock * blocknum;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Read existing buffer or decompress a new block when necessary
|
||||
// Input : **pData - output data pointer
|
||||
// sampleCount - number of samples (or pairs)
|
||||
// Output : int - available samples (zero to stop decoding)
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAudioMixerWaveADPCM::GetOutputData( void **pData, int samplePosition, int sampleCount, bool forward /*= true*/ )
|
||||
{
|
||||
int requestedBlock = GetBlockNumberForSample( samplePosition );
|
||||
if ( requestedBlock != GetCurrentBlock() )
|
||||
{
|
||||
// Ran out of data!!!
|
||||
if ( !SetSamplePosition( samplePosition ) )
|
||||
return 0;
|
||||
}
|
||||
|
||||
Assert( requestedBlock == GetCurrentBlock() );
|
||||
|
||||
if ( m_samplePosition >= m_sampleCount )
|
||||
{
|
||||
if ( !DecodeBlock() )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( m_samplePosition < m_sampleCount )
|
||||
{
|
||||
*pData = (void *)(m_pSamples + m_samplePosition * NumChannels());
|
||||
int available = m_sampleCount - m_samplePosition;
|
||||
if ( available > sampleCount )
|
||||
available = sampleCount;
|
||||
|
||||
m_samplePosition += available;
|
||||
return available;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : position -
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAudioMixerWaveADPCM::SetSamplePosition( int position )
|
||||
{
|
||||
position = max( 0, position );
|
||||
|
||||
CAudioMixerWave::SetSamplePosition( position );
|
||||
|
||||
int requestedBlock = GetBlockNumberForSample( position );
|
||||
int firstSample = GetFirstSampleForBlock( requestedBlock );
|
||||
|
||||
if ( firstSample >= m_pData->Source().SampleCount() )
|
||||
{
|
||||
// Read past end of file!!!
|
||||
return false;
|
||||
}
|
||||
|
||||
int currentSample = ( position - firstSample );
|
||||
|
||||
if ( requestedBlock != GetCurrentBlock() )
|
||||
{
|
||||
// Rewind file to beginning of block
|
||||
m_offset = requestedBlock * m_blockSize;
|
||||
if ( !DecodeBlock() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_samplePosition = currentSample;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Abstract factory function for ADPCM mixers
|
||||
// Input : *data - wave data access object
|
||||
// channels -
|
||||
// Output : CAudioMixer
|
||||
//-----------------------------------------------------------------------------
|
||||
CAudioMixer *CreateADPCMMixer( CWaveData *data )
|
||||
{
|
||||
return new CAudioMixerWaveADPCM( data );
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SND_WAVE_MIXER_ADPCM_H
|
||||
#define SND_WAVE_MIXER_ADPCM_H
|
||||
#pragma once
|
||||
|
||||
|
||||
class CAudioMixer;
|
||||
class CWaveData;
|
||||
|
||||
CAudioMixer *CreateADPCMMixer( CWaveData *data );
|
||||
|
||||
#endif // SND_WAVE_MIXER_ADPCM_H
|
||||
@@ -0,0 +1,94 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SND_WAVE_MIXER_PRIVATE_H
|
||||
#define SND_WAVE_MIXER_PRIVATE_H
|
||||
#pragma once
|
||||
|
||||
#include "snd_audio_source.h"
|
||||
#include "snd_wave_mixer.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Linear iterator over source data.
|
||||
// Keeps track of position in source, and maintains necessary buffers
|
||||
//-----------------------------------------------------------------------------
|
||||
class CWaveData
|
||||
{
|
||||
public:
|
||||
virtual ~CWaveData( void ) {}
|
||||
virtual CAudioSourceWave &Source( void ) = 0;
|
||||
virtual int ReadSourceData( void **pData, int sampleIndex, int sampleCount, bool forward = true ) = 0;
|
||||
};
|
||||
|
||||
class CAudioMixerWave : public CAudioMixer
|
||||
{
|
||||
public:
|
||||
CAudioMixerWave( CWaveData *data );
|
||||
virtual ~CAudioMixerWave( void );
|
||||
|
||||
virtual bool MixDataToDevice( IAudioDevice *pDevice, channel_t *pChannel, int startSample, int sampleCount, int outputRate, bool forward = true );
|
||||
virtual void IncrementSamples( channel_t *pChannel, int startSample, int sampleCount,int outputRate, bool forward = true );
|
||||
virtual bool SkipSamples( channel_t *pChannel, int startSample, int sampleCount,int outputRate, bool forward = true );
|
||||
virtual void Mix( IAudioDevice *pDevice,
|
||||
channel_t *pChannel,
|
||||
void *pData,
|
||||
int outputOffset,
|
||||
int inputOffset,
|
||||
fixedint fracRate,
|
||||
int outCount,
|
||||
int timecompress,
|
||||
bool forward = true ) = 0;
|
||||
|
||||
virtual int GetOutputData( void **pData, int samplePosition, int sampleCount, bool forward = true );
|
||||
|
||||
virtual CAudioSource *GetSource( void );
|
||||
|
||||
virtual int GetSamplePosition( void );
|
||||
|
||||
virtual bool SetSamplePosition( int position );
|
||||
virtual void SetLoopPosition( int position );
|
||||
virtual int GetStartPosition( void );
|
||||
|
||||
virtual bool GetActive( void );
|
||||
virtual void SetActive( bool active );
|
||||
|
||||
virtual void SetModelIndex( int index );
|
||||
virtual int GetModelIndex( void ) const;
|
||||
|
||||
virtual void SetDirection( bool forward );
|
||||
virtual bool GetDirection( void ) const;
|
||||
|
||||
virtual void SetAutoDelete( bool autodelete );
|
||||
virtual bool GetAutoDelete( void ) const;
|
||||
protected:
|
||||
int m_sample;
|
||||
int m_absoluteSample;
|
||||
int m_startpos;
|
||||
int m_loop;
|
||||
int m_fracOffset;
|
||||
CWaveData *m_pData;
|
||||
|
||||
int m_absoluteStartPos;
|
||||
|
||||
bool m_bActive;
|
||||
// Associated playback model in faceposer
|
||||
int m_nModelIndex;
|
||||
|
||||
bool m_bForward;
|
||||
|
||||
bool m_bAutoDelete;
|
||||
};
|
||||
|
||||
|
||||
#endif // SND_WAVE_MIXER_PRIVATE_H
|
||||
@@ -0,0 +1,590 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include "tier2/riff.h"
|
||||
#include "snd_wave_source.h"
|
||||
#include "snd_wave_mixer_private.h"
|
||||
#include "snd_audio_source.h"
|
||||
#include <mmsystem.h> // wave format
|
||||
#include <mmreg.h> // adpcm format
|
||||
#include "filesystem.h"
|
||||
#include "utlbuffer.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Implements the RIFF i/o interface on stdio
|
||||
//-----------------------------------------------------------------------------
|
||||
class StdIOReadBinary : public IFileReadBinary
|
||||
{
|
||||
public:
|
||||
int open( const char *pFileName )
|
||||
{
|
||||
return (int)filesystem->Open( pFileName, "rb" );
|
||||
}
|
||||
|
||||
int read( void *pOutput, int size, int file )
|
||||
{
|
||||
if ( !file )
|
||||
return 0;
|
||||
|
||||
return filesystem->Read( pOutput, size, (FileHandle_t)file );
|
||||
}
|
||||
|
||||
void seek( int file, int pos )
|
||||
{
|
||||
if ( !file )
|
||||
return;
|
||||
|
||||
filesystem->Seek( (FileHandle_t)file, pos, FILESYSTEM_SEEK_HEAD );
|
||||
}
|
||||
|
||||
unsigned int tell( int file )
|
||||
{
|
||||
if ( !file )
|
||||
return 0;
|
||||
|
||||
return filesystem->Tell( (FileHandle_t)file );
|
||||
}
|
||||
|
||||
unsigned int size( int file )
|
||||
{
|
||||
if ( !file )
|
||||
return 0;
|
||||
|
||||
return filesystem->Size( (FileHandle_t)file );
|
||||
}
|
||||
|
||||
void close( int file )
|
||||
{
|
||||
if ( !file )
|
||||
return;
|
||||
|
||||
filesystem->Close( (FileHandle_t)file );
|
||||
}
|
||||
};
|
||||
|
||||
static StdIOReadBinary io;
|
||||
|
||||
#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',' ')
|
||||
|
||||
void ChunkError( unsigned int id )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Init to empty wave
|
||||
//-----------------------------------------------------------------------------
|
||||
CAudioSourceWave::CAudioSourceWave( void )
|
||||
{
|
||||
m_format = 0;
|
||||
m_pHeader = NULL;
|
||||
// no looping
|
||||
m_loopStart = -1;
|
||||
m_sampleSize = 1;
|
||||
m_sampleCount = 0;
|
||||
}
|
||||
|
||||
|
||||
CAudioSourceWave::~CAudioSourceWave( void )
|
||||
{
|
||||
// for non-standard waves, we store a copy of the header in RAM
|
||||
delete[] m_pHeader;
|
||||
// m_pWords points into m_pWordBuffer, no need to delete
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Init the wave data.
|
||||
// Input : *pHeaderBuffer - the RIFF fmt chunk
|
||||
// headerSize - size of that chunk
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAudioSourceWave::Init( const char *pHeaderBuffer, int headerSize )
|
||||
{
|
||||
const WAVEFORMATEX *pHeader = (const WAVEFORMATEX *)pHeaderBuffer;
|
||||
|
||||
// copy the relevant header data
|
||||
m_format = pHeader->wFormatTag;
|
||||
m_bits = pHeader->wBitsPerSample;
|
||||
m_rate = pHeader->nSamplesPerSec;
|
||||
m_channels = pHeader->nChannels;
|
||||
|
||||
m_sampleSize = (m_bits * m_channels) / 8;
|
||||
|
||||
// this can never be zero -- other functions divide by this.
|
||||
// This should never happen, but avoid crashing
|
||||
if ( m_sampleSize <= 0 )
|
||||
m_sampleSize = 1;
|
||||
|
||||
// For non-standard waves (like ADPCM) store the header, it has some useful data
|
||||
if ( m_format != WAVE_FORMAT_PCM )
|
||||
{
|
||||
m_pHeader = new char[headerSize];
|
||||
memcpy( m_pHeader, pHeader, headerSize );
|
||||
if ( m_format == WAVE_FORMAT_ADPCM )
|
||||
{
|
||||
// treat ADPCM sources as a file of bytes. They are decoded by the mixer
|
||||
m_sampleSize = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float CAudioSourceWave::TrueSampleSize( void )
|
||||
{
|
||||
if ( m_format == WAVE_FORMAT_ADPCM )
|
||||
{
|
||||
return 0.5f;
|
||||
}
|
||||
return (float)m_sampleSize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Total number of samples in this source
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAudioSourceWave::SampleCount( void )
|
||||
{
|
||||
if ( m_format == WAVE_FORMAT_ADPCM )
|
||||
{
|
||||
ADPCMWAVEFORMAT *pFormat = (ADPCMWAVEFORMAT *)m_pHeader;
|
||||
int blockSize = ((pFormat->wSamplesPerBlock - 2) * pFormat->wfx.nChannels ) / 2;
|
||||
blockSize += 7 * pFormat->wfx.nChannels;
|
||||
|
||||
int blockCount = m_sampleCount / blockSize;
|
||||
int blockRem = m_sampleCount % blockSize;
|
||||
|
||||
// total samples in complete blocks
|
||||
int sampleCount = blockCount * pFormat->wSamplesPerBlock;
|
||||
|
||||
// add remaining in a short block
|
||||
if ( blockRem )
|
||||
{
|
||||
sampleCount += pFormat->wSamplesPerBlock - (((blockSize - blockRem) * 2) / m_channels);
|
||||
}
|
||||
return sampleCount;
|
||||
}
|
||||
return m_sampleCount;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Do any sample conversion
|
||||
// For 8 bit PCM, convert to signed because the mixing routine assumes this
|
||||
// Input : *pData - pointer to sample data
|
||||
// sampleCount - number of samples
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAudioSourceWave::ConvertSamples( char *pData, int sampleCount )
|
||||
{
|
||||
if ( m_format == WAVE_FORMAT_PCM )
|
||||
{
|
||||
if ( m_bits == 8 )
|
||||
{
|
||||
for ( int i = 0; i < sampleCount; i++ )
|
||||
{
|
||||
for ( int j = 0; j < m_channels; j++ )
|
||||
{
|
||||
*pData = (unsigned char)((int)((unsigned)*pData) - 128);
|
||||
pData++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &walk -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAudioSourceWave::ParseSentence( IterateRIFF &walk )
|
||||
{
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
|
||||
buf.EnsureCapacity( walk.ChunkSize() );
|
||||
walk.ChunkRead( buf.Base() );
|
||||
buf.SeekPut( CUtlBuffer::SEEK_HEAD, walk.ChunkSize() );
|
||||
|
||||
m_Sentence.InitFromDataChunk( buf.Base(), buf.TellPut() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Parse base chunks
|
||||
// Input : &walk - riff file to parse
|
||||
// : chunkName - name of the chunk to parse
|
||||
//-----------------------------------------------------------------------------
|
||||
// UNDONE: Move parsing loop here and drop each chunk into a virtual function
|
||||
// instead of this being virtual.
|
||||
void CAudioSourceWave::ParseChunk( IterateRIFF &walk, int chunkName )
|
||||
{
|
||||
switch( chunkName )
|
||||
{
|
||||
case WAVE_CUE:
|
||||
{
|
||||
m_loopStart = ParseCueChunk( walk );
|
||||
}
|
||||
break;
|
||||
case WAVE_VALVEDATA:
|
||||
{
|
||||
ParseSentence( walk );
|
||||
}
|
||||
break;
|
||||
// unknown/don't care
|
||||
default:
|
||||
{
|
||||
ChunkError( walk.ChunkName() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : CSentence
|
||||
//-----------------------------------------------------------------------------
|
||||
CSentence *CAudioSourceWave::GetSentence( void )
|
||||
{
|
||||
return &m_Sentence;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Bastardized construction routine. This is just to avoid complex
|
||||
// constructor functions so code can be shared more easily by sub-classes
|
||||
// Input : *pFormatBuffer - RIFF header
|
||||
// formatSize - header size
|
||||
// &walk - RIFF file
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAudioSourceWave::Setup( const char *pFormatBuffer, int formatSize, IterateRIFF &walk )
|
||||
{
|
||||
Init( pFormatBuffer, formatSize );
|
||||
|
||||
while ( walk.ChunkAvailable() )
|
||||
{
|
||||
ParseChunk( walk, walk.ChunkName() );
|
||||
walk.ChunkNext();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Wave file that is completely in memory
|
||||
// UNDONE: Implement Lock/Unlock and caching
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAudioSourceMemWave : public CAudioSourceWave
|
||||
{
|
||||
public:
|
||||
CAudioSourceMemWave( void );
|
||||
~CAudioSourceMemWave( void );
|
||||
|
||||
// Create an instance (mixer) of this audio source
|
||||
virtual CAudioMixer *CreateMixer( void );
|
||||
|
||||
virtual void ParseChunk( IterateRIFF &walk, int chunkName );
|
||||
void ParseDataChunk( IterateRIFF &walk );
|
||||
|
||||
virtual int GetOutputData( void **pData, int samplePosition, int sampleCount, bool forward = true );
|
||||
virtual float GetRunningLength( void ) { return CAudioSourceWave::GetRunningLength(); };
|
||||
|
||||
private:
|
||||
char *m_pData; // wave data
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Iterator for wave data (this is to abstract streaming/buffering)
|
||||
//-----------------------------------------------------------------------------
|
||||
class CWaveDataMemory : public CWaveData
|
||||
{
|
||||
public:
|
||||
CWaveDataMemory( CAudioSourceWave &source ) : m_source(source) {}
|
||||
~CWaveDataMemory( void ) {}
|
||||
CAudioSourceWave &Source( void ) { return m_source; }
|
||||
|
||||
// this file is in memory, simply pass along the data request to the source
|
||||
virtual int ReadSourceData( void **pData, int sampleIndex, int sampleCount, bool forward /*= true*/ )
|
||||
{
|
||||
return m_source.GetOutputData( pData, sampleIndex, sampleCount, forward );
|
||||
}
|
||||
private:
|
||||
CAudioSourceWave &m_source; // pointer to source
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: NULL the wave data pointer (we haven't loaded yet)
|
||||
//-----------------------------------------------------------------------------
|
||||
CAudioSourceMemWave::CAudioSourceMemWave( void )
|
||||
{
|
||||
m_pData = NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Free any wave data we've allocated
|
||||
//-----------------------------------------------------------------------------
|
||||
CAudioSourceMemWave::~CAudioSourceMemWave( void )
|
||||
{
|
||||
delete[] m_pData;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Creates a mixer and initializes it with an appropriate mixer
|
||||
//-----------------------------------------------------------------------------
|
||||
CAudioMixer *CAudioSourceMemWave::CreateMixer( void )
|
||||
{
|
||||
return CreateWaveMixer( new CWaveDataMemory(*this), m_format, m_channels, m_bits );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: parse chunks with unique processing to in-memory waves
|
||||
// Input : &walk - RIFF file
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAudioSourceMemWave::ParseChunk( IterateRIFF &walk, int chunkName )
|
||||
{
|
||||
switch( chunkName )
|
||||
{
|
||||
// this is the audio data
|
||||
case WAVE_DATA:
|
||||
{
|
||||
ParseDataChunk( walk );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CAudioSourceWave::ParseChunk( walk, chunkName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: reads the actual sample data and parses it
|
||||
// Input : &walk - RIFF file
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAudioSourceMemWave::ParseDataChunk( IterateRIFF &walk )
|
||||
{
|
||||
int size = walk.ChunkSize();
|
||||
|
||||
// create a buffer for the samples
|
||||
m_pData = new char[size];
|
||||
|
||||
// load them into memory
|
||||
walk.ChunkRead( m_pData );
|
||||
|
||||
if ( m_format == WAVE_FORMAT_PCM )
|
||||
{
|
||||
// number of samples loaded
|
||||
m_sampleCount = size / m_sampleSize;
|
||||
|
||||
// some samples need to be converted
|
||||
ConvertSamples( m_pData, m_sampleCount );
|
||||
}
|
||||
else if ( m_format == WAVE_FORMAT_ADPCM )
|
||||
{
|
||||
// The ADPCM mixers treat the wave source as a flat file of bytes.
|
||||
m_sampleSize = 1;
|
||||
// Since each "sample" is a byte (this is a flat file), the number of samples is the file size
|
||||
m_sampleCount = size;
|
||||
|
||||
// file says 4, output is 16
|
||||
m_bits = 16;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: parses loop information from a cue chunk
|
||||
// Input : &walk - RIFF iterator
|
||||
// Output : int loop start position
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAudioSourceWave::ParseCueChunk( IterateRIFF &walk )
|
||||
{
|
||||
// Cue chunk as specified by RIFF format
|
||||
// see $/research/jay/sound/riffnew.htm
|
||||
struct
|
||||
{
|
||||
unsigned int dwName;
|
||||
unsigned int dwPosition;
|
||||
unsigned int fccChunk;
|
||||
unsigned int dwChunkStart;
|
||||
unsigned int dwBlockStart;
|
||||
unsigned int dwSampleOffset;
|
||||
} cue_chunk;
|
||||
|
||||
int cueCount;
|
||||
|
||||
// assume that the cue chunk stored in the wave is the start of the loop
|
||||
// assume only one cue chunk, UNDONE: Test this assumption here?
|
||||
cueCount = walk.ChunkReadInt();
|
||||
|
||||
walk.ChunkReadPartial( &cue_chunk, sizeof(cue_chunk) );
|
||||
return cue_chunk.dwSampleOffset;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: get the wave header
|
||||
//-----------------------------------------------------------------------------
|
||||
void *CAudioSourceWave::GetHeader( void )
|
||||
{
|
||||
return m_pHeader;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: wrap the position wrt looping
|
||||
// Input : samplePosition - absolute position
|
||||
// Output : int - looped position
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAudioSourceWave::ConvertLoopedPosition( int samplePosition )
|
||||
{
|
||||
// if the wave is looping and we're past the end of the sample
|
||||
// convert to a position within the loop
|
||||
// At the end of the loop, we return a short buffer, and subsequent call
|
||||
// will loop back and get the rest of the buffer
|
||||
if ( m_loopStart >= 0 )
|
||||
{
|
||||
if ( samplePosition >= m_sampleCount )
|
||||
{
|
||||
// size of loop
|
||||
int loopSize = m_sampleCount - m_loopStart;
|
||||
// subtract off starting bit of the wave
|
||||
samplePosition -= m_loopStart;
|
||||
|
||||
if ( loopSize )
|
||||
{
|
||||
// "real" position in memory (mod off extra loops)
|
||||
samplePosition = m_loopStart + (samplePosition % loopSize);
|
||||
}
|
||||
// ERROR? if no loopSize
|
||||
}
|
||||
}
|
||||
|
||||
return samplePosition;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : **pData - output pointer to samples
|
||||
// samplePosition - position (in samples not bytes)
|
||||
// sampleCount - number of samples (not bytes)
|
||||
// Output : int - number of samples available
|
||||
//-----------------------------------------------------------------------------
|
||||
int CAudioSourceMemWave::GetOutputData( void **pData, int samplePosition, int sampleCount, bool forward /*= true*/ )
|
||||
{
|
||||
// handle position looping
|
||||
samplePosition = ConvertLoopedPosition( samplePosition );
|
||||
|
||||
// how many samples are available (linearly not counting looping)
|
||||
int availableSampleCount = m_sampleCount - samplePosition;
|
||||
if ( !forward )
|
||||
{
|
||||
if ( samplePosition >= m_sampleCount )
|
||||
{
|
||||
availableSampleCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
availableSampleCount = samplePosition;
|
||||
}
|
||||
}
|
||||
|
||||
// may be asking for a sample out of range, clip at zero
|
||||
if ( availableSampleCount < 0 )
|
||||
availableSampleCount = 0;
|
||||
|
||||
// clip max output samples to max available
|
||||
if ( sampleCount > availableSampleCount )
|
||||
sampleCount = availableSampleCount;
|
||||
|
||||
// byte offset in sample database
|
||||
samplePosition *= m_sampleSize;
|
||||
|
||||
// if we are returning some samples, store the pointer
|
||||
if ( sampleCount )
|
||||
{
|
||||
*pData = m_pData + samplePosition;
|
||||
}
|
||||
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Create a wave audio source (streaming or in memory)
|
||||
// Input : *pName - file name
|
||||
// streaming - if true, don't load, stream each instance
|
||||
// Output : CAudioSource * - a new source
|
||||
//-----------------------------------------------------------------------------
|
||||
// UNDONE : Pool these and check for duplicates?
|
||||
CAudioSource *CreateWave( const char *pName )
|
||||
{
|
||||
char formatBuffer[1024];
|
||||
InFileRIFF riff( pName, io );
|
||||
|
||||
// UNDONE: Don't use printf to handle errors
|
||||
if ( riff.RIFFName() != RIFF_WAVE )
|
||||
{
|
||||
printf("Bad RIFF file type %s\n", pName );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// set up the iterator for the whole file (root RIFF is a chunk)
|
||||
IterateRIFF walk( riff, riff.RIFFSize() );
|
||||
|
||||
int format = 0;
|
||||
int formatSize = 0;
|
||||
|
||||
// This chunk must be first as it contains the wave's format
|
||||
// break out when we've parsed it
|
||||
while ( walk.ChunkAvailable() && format == 0 )
|
||||
{
|
||||
switch( walk.ChunkName() )
|
||||
{
|
||||
case WAVE_FMT:
|
||||
{
|
||||
if ( walk.ChunkSize() <= 1024 )
|
||||
{
|
||||
walk.ChunkRead( formatBuffer );
|
||||
formatSize = walk.ChunkSize();
|
||||
format = ((WAVEFORMATEX *)formatBuffer)->wFormatTag;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ChunkError( walk.ChunkName() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
walk.ChunkNext();
|
||||
}
|
||||
|
||||
// Not really a WAVE file or no format chunk, bail
|
||||
if ( !format )
|
||||
return NULL;
|
||||
|
||||
CAudioSourceWave *pWave;
|
||||
|
||||
// create the source from this file
|
||||
pWave = new CAudioSourceMemWave();
|
||||
|
||||
// init the wave source
|
||||
pWave->Setup( formatBuffer, formatSize, walk );
|
||||
|
||||
return pWave;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Wrapper for CreateWave()
|
||||
//-----------------------------------------------------------------------------
|
||||
CAudioSource *Audio_CreateMemoryWave( const char *pName )
|
||||
{
|
||||
return CreateWave( pName );
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SND_WAVE_SOURCE_H
|
||||
#define SND_WAVE_SOURCE_H
|
||||
#pragma once
|
||||
|
||||
#include "snd_audio_source.h"
|
||||
#include "sentence.h"
|
||||
|
||||
class IterateRIFF;
|
||||
|
||||
class CAudioSourceWave : public CAudioSource
|
||||
{
|
||||
public:
|
||||
CAudioSourceWave( void );
|
||||
~CAudioSourceWave( void );
|
||||
|
||||
void Setup( const char *pFormat, int formatSize, IterateRIFF &walk );
|
||||
|
||||
virtual int SampleRate( void ) { return m_rate; }
|
||||
inline int SampleSize( void ) { return m_sampleSize; }
|
||||
virtual float TrueSampleSize( void );
|
||||
|
||||
void *GetHeader( void );
|
||||
|
||||
// Legacy
|
||||
virtual void ParseChunk( IterateRIFF &walk, int chunkName );
|
||||
|
||||
virtual void ParseSentence( IterateRIFF &walk );
|
||||
|
||||
void ConvertSamples( char *pData, int sampleCount );
|
||||
bool IsLooped( void ) { return (m_loopStart >= 0) ? true : false; }
|
||||
bool IsStreaming( void ) { return false; }
|
||||
int ConvertLoopedPosition( int samplePosition );
|
||||
|
||||
int SampleCount( void );
|
||||
|
||||
virtual float GetRunningLength( void )
|
||||
{
|
||||
if ( m_rate > 0.0 )
|
||||
{
|
||||
return (float)SampleCount() / m_rate;
|
||||
}
|
||||
return 0.0f; }
|
||||
|
||||
CSentence *GetSentence( void );
|
||||
|
||||
protected:
|
||||
// returns the loop start from a cue chunk
|
||||
int ParseCueChunk( IterateRIFF &walk );
|
||||
void Init( const char *pHeaderBuffer, int headerSize );
|
||||
|
||||
int m_bits;
|
||||
int m_rate;
|
||||
int m_channels;
|
||||
int m_format;
|
||||
int m_sampleSize;
|
||||
int m_loopStart;
|
||||
int m_sampleCount;
|
||||
|
||||
private:
|
||||
char *m_pHeader;
|
||||
CSentence m_Sentence;
|
||||
};
|
||||
|
||||
#endif // SND_WAVE_SOURCE_H
|
||||
@@ -0,0 +1,97 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#ifndef SOUND_H
|
||||
#define SOUND_H
|
||||
#pragma once
|
||||
|
||||
class CAudioMixer;
|
||||
|
||||
class CAudioInput
|
||||
{
|
||||
public:
|
||||
// factory to create a suitable audio input for this system
|
||||
static CAudioInput *Create( void );
|
||||
|
||||
// base class needs virtual destructor
|
||||
virtual ~CAudioInput( void ) {}
|
||||
|
||||
// ------------------- interface ------------------------
|
||||
|
||||
// Returns the current count of available samples
|
||||
virtual int SampleCount( void ) = 0;
|
||||
|
||||
// returns the size of each sample in bytes
|
||||
virtual int SampleSize( void ) = 0;
|
||||
|
||||
// returns the sampling rate of the data
|
||||
virtual int SampleRate( void ) = 0;
|
||||
|
||||
// returns a pointer to the available data
|
||||
virtual void *SampleData( void ) = 0;
|
||||
|
||||
// release the available data (mark as done)
|
||||
virtual void SampleRelease( void ) = 0;
|
||||
|
||||
// returns the mono/stereo status of this device (true if stereo)
|
||||
virtual bool IsStereo( void ) = 0;
|
||||
|
||||
// begin sampling
|
||||
virtual void Start( void ) = 0;
|
||||
|
||||
// stop sampling
|
||||
virtual void Stop( void ) = 0;
|
||||
};
|
||||
|
||||
class CAudioSource;
|
||||
|
||||
class CAudioOutput
|
||||
{
|
||||
public:
|
||||
// factory to create a suitable audio output for this system
|
||||
static CAudioOutput *Create( void );
|
||||
|
||||
// base class needs virtual destructor
|
||||
virtual ~CAudioOutput( void ) {}
|
||||
|
||||
// ------------------- interface ------------------------
|
||||
|
||||
// returns the size of each sample in bytes
|
||||
virtual int SampleSize( void ) = 0;
|
||||
|
||||
// returns the sampling rate of the data
|
||||
virtual int SampleRate( void ) = 0;
|
||||
|
||||
// returns the mono/stereo status of this device (true if stereo)
|
||||
virtual bool IsStereo( void ) = 0;
|
||||
|
||||
// move up to time (time is absolute)
|
||||
virtual void Update( float dt ) = 0;
|
||||
|
||||
virtual void Flush( void ) = 0;
|
||||
|
||||
// Hook up a filter to the input channel
|
||||
virtual void AddSource( CAudioMixer *pSource ) = 0;
|
||||
|
||||
virtual void StopSounds( void ) = 0;
|
||||
|
||||
virtual void FreeChannel( int channel ) = 0;
|
||||
|
||||
virtual int FindSourceIndex( CAudioMixer *pSource ) = 0;
|
||||
|
||||
virtual float GetAmountofTimeAhead( void ) = 0;
|
||||
|
||||
virtual int GetNumberofSamplesAhead( void ) = 0;
|
||||
|
||||
virtual CAudioMixer *GetMixerForSource( CAudioSource *pDevice ) = 0;
|
||||
};
|
||||
|
||||
|
||||
int AudioResample( void *pInput, int inCount, int inSize, bool inStereo, int inRate,
|
||||
void *pOutput, int outCount, int outSize, bool outStereo, int outRate );
|
||||
|
||||
#endif // SOUND_H
|
||||
@@ -0,0 +1,964 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "workspacebrowser.h"
|
||||
#include "workspace.h"
|
||||
#include "project.h"
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
#include "project.h"
|
||||
#include "vcdfile.h"
|
||||
#include "soundentry.h"
|
||||
#include "scene.h"
|
||||
|
||||
#include "workspacemanager.h"
|
||||
#include "soundbrowser.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "iscenemanagersound.h"
|
||||
#include "snd_wave_source.h"
|
||||
#include "cmdlib.h"
|
||||
#include "tabwindow.h"
|
||||
#include "soundproperties.h"
|
||||
#include "soundproperties_multiple.h"
|
||||
#include "wavebrowser.h"
|
||||
#include "wavefile.h"
|
||||
#include "inputproperties.h"
|
||||
#include "drawhelper.h"
|
||||
#include "utlbuffer.h"
|
||||
|
||||
#define ENTRY_ALLSOUNDS "AllSounds"
|
||||
#define ENTRY_ALL_INDEX 0
|
||||
#define ENTRY_SEARCHRESULTS "Search results"
|
||||
#define ENTRY_SEARCH_INDEX 1
|
||||
|
||||
enum
|
||||
{
|
||||
// Controls
|
||||
IDC_SB_LISTVIEW = 101,
|
||||
IDC_SB_FILTERTAB,
|
||||
|
||||
// Messages
|
||||
IDC_SB_PLAY = 1000,
|
||||
IDC_SB_SOUNDPROPERTIES,
|
||||
IDC_SB_SHOWINWAVEBROWSER,
|
||||
IDC_SB_ADDSOUND,
|
||||
IDC_SB_REMOVESOUND,
|
||||
IDC_SB_GETSENTENCE,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
COL_SOUND = 0,
|
||||
COL_COUNT,
|
||||
COL_WAV,
|
||||
COL_SENTENCE,
|
||||
COL_CHANNEL,
|
||||
COL_VOLUME,
|
||||
COL_SOUNDLEVEL,
|
||||
COL_PITCH,
|
||||
COL_SCRIPT,
|
||||
COL_CC,
|
||||
};
|
||||
|
||||
class CSoundList : public mxListView
|
||||
{
|
||||
public:
|
||||
CSoundList( mxWindow *parent, int id = 0 )
|
||||
: mxListView( parent, 0, 0, 0, 0, id )
|
||||
{
|
||||
// SendMessage ( (HWND)getHandle(), WM_SETFONT, (WPARAM) (HFONT) GetStockObject (ANSI_FIXED_FONT), MAKELPARAM (TRUE, 0));
|
||||
|
||||
//HWND wnd = (HWND)getHandle();
|
||||
//DWORD style = GetWindowLong( wnd, GWL_STYLE );
|
||||
//style |= LVS_SORTASCENDING;
|
||||
//SetWindowLong( wnd, GWL_STYLE, style );
|
||||
|
||||
//SceneManager_AddWindowStyle( this, LVS_SORTASCENDING );
|
||||
|
||||
// Add column headers
|
||||
insertTextColumn( COL_SOUND, 200, "Sound" );
|
||||
insertTextColumn( COL_COUNT, 20, "#" );
|
||||
insertTextColumn( COL_WAV, 220, "WAV Filename" );
|
||||
insertTextColumn( COL_SENTENCE, 300, "Sentence Text" );
|
||||
insertTextColumn( COL_CHANNEL, 100, "Channel" );
|
||||
insertTextColumn( COL_VOLUME, 100, "Volume" );
|
||||
insertTextColumn( COL_SOUNDLEVEL, 120, "Soundlevel" );
|
||||
insertTextColumn( COL_PITCH, 100, "Pitch" );
|
||||
insertTextColumn( COL_SCRIPT, 150, "Script File" );
|
||||
insertTextColumn( COL_CC, 300, "CC Text" );
|
||||
}
|
||||
};
|
||||
|
||||
class CSoundFilterTab : public CTabWindow
|
||||
{
|
||||
public:
|
||||
typedef CTabWindow BaseClass;
|
||||
|
||||
CSoundFilterTab( mxWindow *parent, int x, int y, int w, int h, int id = 0, int style = 0 ) :
|
||||
CTabWindow( parent, x, y, w, h, id, style )
|
||||
{
|
||||
SetInverted( true );
|
||||
SetRowHeight( 20 );
|
||||
}
|
||||
|
||||
virtual void ShowRightClickMenu( int mx, int my )
|
||||
{
|
||||
// Nothing
|
||||
}
|
||||
|
||||
void Init( CUtlSymbolTable& table, CUtlVector< CUtlSymbol >& scripts )
|
||||
{
|
||||
add( ENTRY_ALLSOUNDS );
|
||||
add( ENTRY_SEARCHRESULTS );
|
||||
|
||||
int c = scripts.Count();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
CUtlSymbol& sym = scripts[ i ];
|
||||
add( table.String( sym ) );
|
||||
}
|
||||
select( 0 );
|
||||
}
|
||||
|
||||
void UpdatePrefixes()
|
||||
{
|
||||
int c = getItemCount();
|
||||
// Skip All and search results
|
||||
for ( int i = 2; i < c; i++ )
|
||||
{
|
||||
setPrefix( i, "" );
|
||||
|
||||
char const *script = getLabel( i );
|
||||
if ( !script )
|
||||
continue;
|
||||
|
||||
int scriptindex = g_pSoundEmitterSystem->FindSoundScript( va( "scripts/%s.txt", script ) );
|
||||
if ( scriptindex < 0 )
|
||||
continue;
|
||||
|
||||
if ( g_pSoundEmitterSystem->IsSoundScriptDirty( scriptindex ) )
|
||||
{
|
||||
setPrefix( i, "* " );
|
||||
}
|
||||
}
|
||||
|
||||
RecomputeLayout( w2() );
|
||||
redraw();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class COptionsWindow : public mxWindow
|
||||
{
|
||||
typedef mxWindow BaseClass;
|
||||
public:
|
||||
enum
|
||||
{
|
||||
IDC_VOICE_ONLY = 1000,
|
||||
IDC_PLAY_SOUND,
|
||||
IDC_STOP_SOUNDS,
|
||||
IDC_SEARCH,
|
||||
};
|
||||
|
||||
COptionsWindow( CSoundBrowser *browser ) : BaseClass( browser, 0, 0, 0, 0 ), m_pBrowser( browser )
|
||||
{
|
||||
SceneManager_AddWindowStyle( this, WS_CLIPSIBLINGS | WS_CLIPCHILDREN );
|
||||
|
||||
m_szSearchString[0]=0;
|
||||
|
||||
m_pChanVoiceOnly = new mxCheckBox( this, 0, 0, 0, 0, "CHAN_VOICE only", IDC_VOICE_ONLY );
|
||||
m_pChanVoiceOnly->setChecked( true );
|
||||
|
||||
m_pPlay = new mxButton( this, 0, 0, 0, 0, "Play", IDC_PLAY_SOUND );
|
||||
|
||||
m_pStopSounds = new mxButton( this, 0, 0, 0, 0, "Stop Sounds", IDC_STOP_SOUNDS );
|
||||
|
||||
m_pSearch = new mxButton( this, 0, 0, 0, 0, "Search...", IDC_SEARCH );
|
||||
|
||||
m_pSearchString = new mxLabel( this, 0, 0, 0, 0, "" );
|
||||
}
|
||||
|
||||
bool PaintBackground( void )
|
||||
{
|
||||
redraw();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual void redraw()
|
||||
{
|
||||
CDrawHelper drawHelper( this, 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_pChanVoiceOnly->setBounds( x, 1, split, h2() - 2 );
|
||||
|
||||
x += split + 10;
|
||||
|
||||
m_pSearch->setBounds( x, 1, split, h2() - 2 );
|
||||
|
||||
x += split + 10;
|
||||
|
||||
m_pSearchString->setBounds( x, 2, split * 2, h2() - 4 );
|
||||
|
||||
x += split * 2 + 10;
|
||||
|
||||
}
|
||||
break;
|
||||
case mxEvent::Action:
|
||||
{
|
||||
switch ( event->action )
|
||||
{
|
||||
case IDC_STOP_SOUNDS:
|
||||
{
|
||||
iret = 1;
|
||||
sound->StopAll();
|
||||
}
|
||||
break;
|
||||
case IDC_PLAY_SOUND:
|
||||
{
|
||||
iret = 1;
|
||||
m_pBrowser->OnPlay();
|
||||
}
|
||||
break;
|
||||
case IDC_VOICE_ONLY:
|
||||
{
|
||||
iret = 1;
|
||||
m_pBrowser->RepopulateTree();
|
||||
};
|
||||
break;
|
||||
case IDC_SEARCH:
|
||||
{
|
||||
iret = 1;
|
||||
OnSearch();
|
||||
};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return iret;
|
||||
}
|
||||
|
||||
bool IsChanVoiceOnly() const
|
||||
{
|
||||
return m_pChanVoiceOnly->isChecked();
|
||||
}
|
||||
|
||||
char const *GetSearchString()
|
||||
{
|
||||
return m_szSearchString;
|
||||
}
|
||||
|
||||
void OnSearch()
|
||||
{
|
||||
CInputParams params;
|
||||
memset( ¶ms, 0, sizeof( params ) );
|
||||
Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Search" );
|
||||
Q_strcpy( params.m_szPrompt, "Find:" );
|
||||
Q_strcpy( params.m_szInputText, m_szSearchString );
|
||||
|
||||
if ( !InputProperties( ¶ms ) )
|
||||
return;
|
||||
|
||||
Q_strcpy( m_szSearchString, params.m_szInputText );
|
||||
|
||||
m_pSearchString->setLabel( va( "Search: '%s'", GetSearchString() ) );
|
||||
|
||||
m_pBrowser->OnSearch();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
mxCheckBox *m_pChanVoiceOnly;
|
||||
mxButton *m_pStopSounds;
|
||||
mxButton *m_pPlay;
|
||||
mxButton *m_pSearch;
|
||||
mxLabel *m_pSearchString;
|
||||
|
||||
CSoundBrowser *m_pBrowser;
|
||||
|
||||
char m_szSearchString[ 256 ];
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *parent -
|
||||
//-----------------------------------------------------------------------------
|
||||
CSoundBrowser::CSoundBrowser( mxWindow *parent, CWorkspaceManager *manager, int id ) :
|
||||
BaseClass( parent, 0, 0, 0, 0, "Sound Browser", id )
|
||||
{
|
||||
m_pManager = manager;
|
||||
|
||||
SceneManager_MakeToolWindow( this, false );
|
||||
|
||||
m_pListView = new CSoundList( this, IDC_SB_LISTVIEW );
|
||||
m_pFilter = new CSoundFilterTab( this, 0, 0, 0, 0, IDC_SB_FILTERTAB );
|
||||
m_pOptions = new COptionsWindow( this );
|
||||
|
||||
HIMAGELIST list = GetWorkspaceManager()->CreateImageList();
|
||||
|
||||
// Associate the image list with the tree-view control.
|
||||
m_pListView->setImageList( (void *)list );
|
||||
|
||||
LoadAllSounds();
|
||||
|
||||
m_pFilter->select( 0 );
|
||||
RepopulateTree();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundBrowser::OnDelete()
|
||||
{
|
||||
RemoveAllSounds();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *event -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CSoundBrowser::handleEvent( mxEvent *event )
|
||||
{
|
||||
int iret = 0;
|
||||
switch ( event->event )
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case mxEvent::Action:
|
||||
{
|
||||
iret = 1;
|
||||
switch ( event->action )
|
||||
{
|
||||
default:
|
||||
{
|
||||
iret = 0;
|
||||
}
|
||||
break;
|
||||
case IDC_SB_FILTERTAB:
|
||||
{
|
||||
RepopulateTree();
|
||||
}
|
||||
break;
|
||||
case IDC_SB_LISTVIEW:
|
||||
{
|
||||
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 )
|
||||
{
|
||||
CSoundEntry *se = (CSoundEntry *)m_pListView->getUserData( index, 0 );
|
||||
if ( se )
|
||||
{
|
||||
se->Play();
|
||||
|
||||
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser();
|
||||
if ( wb && se->GetWaveCount() > 0 )
|
||||
{
|
||||
CWaveFile *firstwave = se->GetWave( 0 );
|
||||
Assert( firstwave );
|
||||
if ( firstwave )
|
||||
{
|
||||
wb->JumpToItem( firstwave );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDC_SB_PLAY:
|
||||
{
|
||||
OnPlay();
|
||||
}
|
||||
break;
|
||||
case IDC_SB_GETSENTENCE:
|
||||
{
|
||||
OnGetSentence();
|
||||
}
|
||||
break;
|
||||
case IDC_SB_SOUNDPROPERTIES:
|
||||
{
|
||||
OnSoundProperties();
|
||||
}
|
||||
break;
|
||||
case IDC_SB_SHOWINWAVEBROWSER:
|
||||
{
|
||||
OnShowInWaveBrowser();
|
||||
}
|
||||
break;
|
||||
case IDC_SB_ADDSOUND:
|
||||
{
|
||||
OnAddSound();
|
||||
}
|
||||
break;
|
||||
case IDC_SB_REMOVESOUND:
|
||||
{
|
||||
OnRemoveSound();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case mxEvent::Size:
|
||||
{
|
||||
int optionsh = 20;
|
||||
int filterh = m_pFilter->GetBestHeight( w2() );
|
||||
|
||||
m_pOptions->setBounds( 0, 0, w2(), optionsh );
|
||||
m_pListView->setBounds( 0, optionsh, w2(), h2() - filterh - optionsh );
|
||||
m_pFilter->setBounds( 0, h2() - filterh, w2(), filterh );
|
||||
|
||||
GetWorkspaceManager()->SetWorkspaceDirty();
|
||||
|
||||
iret = 1;
|
||||
}
|
||||
break;
|
||||
case mxEvent::Close:
|
||||
{
|
||||
iret = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return iret;
|
||||
}
|
||||
|
||||
static bool NameLessFunc( CSoundEntry *const& name1, CSoundEntry *const& name2 )
|
||||
{
|
||||
if ( Q_stricmp( name1->GetName(), name2->GetName() ) < 0 )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CSoundBrowser::LoadAllSounds()
|
||||
{
|
||||
RemoveAllSounds();
|
||||
|
||||
// int c = g_pSoundEmitterSystem->GetSoundCount();
|
||||
int added = 0;
|
||||
|
||||
int i;
|
||||
for ( i = g_pSoundEmitterSystem->First(); i != g_pSoundEmitterSystem->InvalidIndex(); i = g_pSoundEmitterSystem->Next( i ) )
|
||||
{
|
||||
char const *name = g_pSoundEmitterSystem->GetSoundName( i );
|
||||
CSoundEntry *se = new CSoundEntry( NULL, name );
|
||||
m_AllSounds.AddToTail( se );
|
||||
|
||||
char filebase [ 512 ];
|
||||
Q_FileBase( g_pSoundEmitterSystem->GetSourceFileForSound( i ), filebase, sizeof( filebase ) );
|
||||
|
||||
// Add script file symbol
|
||||
CUtlSymbol script_sym = m_ScriptTable.AddString( filebase );
|
||||
|
||||
if ( m_Scripts.Find( script_sym ) == m_Scripts.InvalidIndex() )
|
||||
{
|
||||
m_Scripts.AddToTail( script_sym );
|
||||
}
|
||||
|
||||
++added;
|
||||
|
||||
if ( !( added % 500 ) )
|
||||
{
|
||||
// Con_Printf( "CSoundBrowser: loaded %i sounds\n", added );
|
||||
}
|
||||
}
|
||||
|
||||
m_pFilter->Init( m_ScriptTable, m_Scripts );
|
||||
}
|
||||
|
||||
void CSoundBrowser::RemoveAllSounds()
|
||||
{
|
||||
int c = m_AllSounds.Count();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
CSoundEntry *se = m_AllSounds[ i ];
|
||||
delete se;
|
||||
}
|
||||
|
||||
m_AllSounds.RemoveAll();
|
||||
m_Scripts.RemoveAll();
|
||||
m_CurrentSelection.RemoveAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundBrowser::PopulateTree( bool voiceonly, char const *scriptonly )
|
||||
{
|
||||
int i;
|
||||
|
||||
CUtlRBTree< CSoundEntry *, int > m_Sorted( 0, 0, NameLessFunc );
|
||||
|
||||
bool textsearch = false;
|
||||
char const *texttofind = NULL;
|
||||
|
||||
if ( scriptonly )
|
||||
{
|
||||
if ( !Q_stricmp( scriptonly, ENTRY_ALLSOUNDS ) )
|
||||
{
|
||||
scriptonly = NULL;
|
||||
}
|
||||
else if ( !Q_stricmp( scriptonly, ENTRY_SEARCHRESULTS ) )
|
||||
{
|
||||
scriptonly = NULL;
|
||||
textsearch = true;
|
||||
texttofind = GetSearchString();
|
||||
}
|
||||
}
|
||||
|
||||
int c = m_AllSounds.Count();
|
||||
for ( i = 0; i < c; i++ )
|
||||
{
|
||||
CSoundEntry *se = m_AllSounds[ i ];
|
||||
char const *name = se->GetName();
|
||||
|
||||
CSoundParametersInternal *params = se->GetSoundParameters();
|
||||
if ( !params )
|
||||
continue;
|
||||
|
||||
if ( voiceonly && params->GetChannel() != CHAN_VOICE )
|
||||
continue;
|
||||
|
||||
if ( scriptonly )
|
||||
{
|
||||
if ( Q_stricmp( scriptonly, se->GetScriptFile() ) )
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( textsearch && texttofind )
|
||||
{
|
||||
bool keep = false;
|
||||
if ( Q_stristr( name, texttofind ) )
|
||||
{
|
||||
keep = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int waveCount = se->GetWaveCount();
|
||||
for ( int wave = 0; wave < waveCount; wave++ )
|
||||
{
|
||||
CWaveFile *w = se->GetWave( wave );
|
||||
if ( !w )
|
||||
continue;
|
||||
|
||||
char const *wavename = w->GetFileName();
|
||||
if ( !wavename )
|
||||
{
|
||||
Assert( 0 );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !Q_stristr( wavename, texttofind ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
keep = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( !keep )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
m_Sorted.Insert( se );
|
||||
}
|
||||
|
||||
|
||||
// Repopulate tree
|
||||
m_pListView->removeAll();
|
||||
|
||||
int loadcount = 0;
|
||||
|
||||
m_pListView->setDrawingEnabled( false );
|
||||
|
||||
for ( i = m_Sorted.FirstInorder(); i != m_Sorted.InvalidIndex(); i = m_Sorted.NextInorder( i ) )
|
||||
{
|
||||
CSoundEntry *se = m_Sorted[ i ];
|
||||
char const *name = se->GetName();
|
||||
CSoundParametersInternal *params = se->GetSoundParameters();
|
||||
if ( !params )
|
||||
continue;
|
||||
|
||||
int slot = m_pListView->add( name );
|
||||
|
||||
m_pListView->setUserData( slot, COL_SOUND, (void *)se );
|
||||
|
||||
m_pListView->setImage( slot, COL_SOUND, se->GetIconIndex() );
|
||||
|
||||
int waveCount = params->NumSoundNames();
|
||||
|
||||
if ( waveCount >= 1 )
|
||||
{
|
||||
m_pListView->setLabel( slot, COL_COUNT, waveCount > 1 ? va( "%i", waveCount ) : "" );
|
||||
m_pListView->setLabel( slot, COL_WAV, g_pSoundEmitterSystem->GetWaveName( params->GetSoundNames()[ 0 ].symbol ) );
|
||||
}
|
||||
|
||||
m_pListView->setLabel( slot, COL_SENTENCE, se->GetSentenceText( 0 ) );
|
||||
|
||||
m_pListView->setLabel( slot, COL_CHANNEL, params->ChannelToString() );
|
||||
m_pListView->setLabel( slot, COL_VOLUME, params->VolumeToString() );
|
||||
m_pListView->setLabel( slot, COL_SOUNDLEVEL, params->SoundLevelToString() );
|
||||
m_pListView->setLabel( slot, COL_PITCH, params->PitchToString() );
|
||||
|
||||
wchar_t buf[ 1024 ];
|
||||
se->GetCCText( buf, 1024 );
|
||||
m_pListView->setLabel( slot, COL_CC, buf );
|
||||
|
||||
char filebase [ 512 ];
|
||||
|
||||
int soundIndex = g_pSoundEmitterSystem->GetSoundIndex( name );
|
||||
|
||||
Q_FileBase( g_pSoundEmitterSystem->GetSourceFileForSound( soundIndex ), filebase, sizeof( filebase ) );
|
||||
|
||||
m_pListView->setLabel( slot, COL_SCRIPT, filebase );
|
||||
|
||||
++loadcount;
|
||||
}
|
||||
|
||||
m_pListView->setDrawingEnabled( true );
|
||||
|
||||
// Con_Printf( "CSoundBrowser: selected %i sounds\n", loadcount );
|
||||
}
|
||||
|
||||
CWorkspaceManager *CSoundBrowser::GetManager()
|
||||
{
|
||||
return m_pManager;
|
||||
}
|
||||
|
||||
void CSoundBrowser::RepopulateTree()
|
||||
{
|
||||
bool voiceonly = m_pOptions->IsChanVoiceOnly();
|
||||
|
||||
int slot = m_pFilter->getSelectedIndex();
|
||||
|
||||
if ( 0 >= slot )
|
||||
{
|
||||
PopulateTree( voiceonly, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
PopulateTree( voiceonly, m_pFilter->getLabel( slot ) );
|
||||
}
|
||||
|
||||
m_pFilter->UpdatePrefixes();
|
||||
}
|
||||
|
||||
void CSoundBrowser::BuildSelectionList( CUtlVector< CSoundEntry * >& selected )
|
||||
{
|
||||
selected.RemoveAll();
|
||||
|
||||
int idx = -1;
|
||||
do
|
||||
{
|
||||
idx = m_pListView->getNextSelectedItem( idx );
|
||||
if ( idx != -1 )
|
||||
{
|
||||
CSoundEntry *se = (CSoundEntry *)m_pListView->getUserData( idx, 0 );
|
||||
if ( se )
|
||||
{
|
||||
selected.AddToTail( se );
|
||||
}
|
||||
}
|
||||
} while ( idx != -1 );
|
||||
|
||||
}
|
||||
|
||||
void CSoundBrowser::ShowContextMenu( void )
|
||||
{
|
||||
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( "Refresh sentence data", IDC_SB_GETSENTENCE );
|
||||
|
||||
pop->add( "Add sound entry...", IDC_SB_ADDSOUND );
|
||||
if ( m_CurrentSelection.Count() >= 1 )
|
||||
{
|
||||
pop->add( "Remove sound(s)", IDC_SB_REMOVESOUND );
|
||||
}
|
||||
|
||||
pop->addSeparator();
|
||||
|
||||
pop->add( "Show in Wave Browser", IDC_SB_SHOWINWAVEBROWSER );
|
||||
|
||||
pop->add( "&Properties...", IDC_SB_SOUNDPROPERTIES );
|
||||
|
||||
pop->popup( this, pt.x, pt.y );
|
||||
}
|
||||
|
||||
void CSoundBrowser::OnPlay()
|
||||
{
|
||||
BuildSelectionList( m_CurrentSelection );
|
||||
if ( m_CurrentSelection.Count() == 1 )
|
||||
{
|
||||
CSoundEntry *se = m_CurrentSelection[ 0 ];
|
||||
if ( se )
|
||||
{
|
||||
se->Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSoundBrowser::JumpToItem( CSoundEntry *se )
|
||||
{
|
||||
char const *script = se->GetScriptFile();
|
||||
|
||||
bool voiceonly = m_pOptions->IsChanVoiceOnly();
|
||||
|
||||
if ( !script || !script[ 0 ] )
|
||||
{
|
||||
PopulateTree( voiceonly, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
PopulateTree( voiceonly, script );
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
int c = m_pListView->getItemCount();
|
||||
for ( ; idx < c; idx++ )
|
||||
{
|
||||
CSoundEntry *item = (CSoundEntry *)m_pListView->getUserData( idx, 0 );
|
||||
if ( !Q_stricmp( item->GetName(), se->GetName() ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( idx < c )
|
||||
{
|
||||
m_pListView->scrollToItem( idx );
|
||||
}
|
||||
}
|
||||
|
||||
void CSoundBrowser::OnSoundProperties()
|
||||
{
|
||||
BuildSelectionList( m_CurrentSelection );
|
||||
if ( m_CurrentSelection.Count() < 1 )
|
||||
{
|
||||
Con_Printf( "No selection\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
CSoundParams params;
|
||||
memset( ¶ms, 0, sizeof( params ) );
|
||||
|
||||
Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Sound Properties" );
|
||||
|
||||
int c = m_CurrentSelection.Count();
|
||||
for ( int i = 0 ; i < c; i++ )
|
||||
{
|
||||
CSoundEntry *entry = m_CurrentSelection[ i ];
|
||||
if ( !entry )
|
||||
continue;
|
||||
|
||||
params.items.AddToTail( entry );
|
||||
}
|
||||
|
||||
if ( params.items.Count() > 1 )
|
||||
{
|
||||
SoundProperties_Multiple( ¶ms );
|
||||
}
|
||||
else
|
||||
{
|
||||
SoundProperties( ¶ms );
|
||||
}
|
||||
}
|
||||
|
||||
void CSoundBrowser::OnShowInWaveBrowser()
|
||||
{
|
||||
if ( m_pListView->getNumSelected() == 1 )
|
||||
{
|
||||
int index = m_pListView->getNextSelectedItem( -1 );
|
||||
if ( index >= 0 )
|
||||
{
|
||||
CSoundEntry *se = (CSoundEntry *)m_pListView->getUserData( index, 0 );
|
||||
if ( se )
|
||||
{
|
||||
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser();
|
||||
if ( wb && se->GetWaveCount() > 0 )
|
||||
{
|
||||
CWaveFile *firstwave = se->GetWave( 0 );
|
||||
Assert( firstwave );
|
||||
if ( firstwave )
|
||||
{
|
||||
wb->JumpToItem( firstwave );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSoundBrowser::OnSearch()
|
||||
{
|
||||
m_pFilter->select( ENTRY_SEARCH_INDEX );
|
||||
RepopulateTree();
|
||||
}
|
||||
|
||||
char const *CSoundBrowser::GetSearchString()
|
||||
{
|
||||
return m_pOptions->GetSearchString();
|
||||
}
|
||||
|
||||
void CSoundBrowser::OnAddSound()
|
||||
{
|
||||
CSoundParams params;
|
||||
memset( ¶ms, 0, sizeof( params ) );
|
||||
params.addsound = true;
|
||||
|
||||
Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "New Sound" );
|
||||
|
||||
if ( !SoundProperties( ¶ms ) )
|
||||
return;
|
||||
|
||||
if ( params.items.Count() == 1 )
|
||||
{
|
||||
CSoundEntry *newItem = params.items[ 0 ];
|
||||
m_AllSounds.AddToTail( newItem );
|
||||
|
||||
int slot = g_pSoundEmitterSystem->GetSoundIndex( newItem->GetName() );
|
||||
if ( g_pSoundEmitterSystem->IsValidIndex( slot ) )
|
||||
{
|
||||
CSoundParametersInternal *p = g_pSoundEmitterSystem->InternalGetParametersForSound( slot );
|
||||
if ( p )
|
||||
{
|
||||
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser();
|
||||
Assert( wb );
|
||||
|
||||
int waveCount = p->NumSoundNames();
|
||||
for ( int wave = 0; wave < waveCount; wave++ )
|
||||
{
|
||||
char const *wavname = g_pSoundEmitterSystem->GetWaveName( p->GetSoundNames()[ wave ].symbol );
|
||||
if ( wavname )
|
||||
{
|
||||
CWaveFile *wavefile = wb->FindEntry( wavname, true );
|
||||
if ( wavefile )
|
||||
{
|
||||
newItem->AddWave( wavefile );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repopulate things
|
||||
GetWorkspaceManager()->RefreshBrowsers();
|
||||
}
|
||||
|
||||
void CSoundBrowser::OnRemoveSound()
|
||||
{
|
||||
BuildSelectionList( m_CurrentSelection );
|
||||
if ( m_CurrentSelection.Count() < 1 )
|
||||
{
|
||||
Con_Printf( "No selection\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
int c = m_CurrentSelection.Count();
|
||||
for ( int i = c - 1; i >= 0 ; i-- )
|
||||
{
|
||||
CSoundEntry *se = m_CurrentSelection[ i ];
|
||||
Assert( se );
|
||||
|
||||
// FIXME: See if still referenced by a vcd?
|
||||
|
||||
g_pSoundEmitterSystem->RemoveSound( se->GetName() );
|
||||
m_AllSounds.FindAndRemove( se );
|
||||
delete se;
|
||||
}
|
||||
|
||||
// Repopulate things
|
||||
GetWorkspaceManager()->RefreshBrowsers();
|
||||
}
|
||||
|
||||
void CSoundBrowser::OnGetSentence()
|
||||
{
|
||||
BuildSelectionList( m_CurrentSelection );
|
||||
if ( m_CurrentSelection.Count() < 1 )
|
||||
{
|
||||
Con_Printf( "No selection\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
int c = m_CurrentSelection.Count();
|
||||
for ( int i = c - 1; i >= 0 ; i-- )
|
||||
{
|
||||
CSoundEntry *se = m_CurrentSelection[ i ];
|
||||
Assert( se );
|
||||
|
||||
int c = se->GetWaveCount();
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
CWaveFile *wav = se->GetWave( i );
|
||||
if ( !wav->HasLoadedSentenceInfo() )
|
||||
{
|
||||
wav->EnsureSentence();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repopulate things
|
||||
GetWorkspaceManager()->RefreshBrowsers();
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SOUNDBROWSER_H
|
||||
#define SOUNDBROWSER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "mxtk/mxListView.h"
|
||||
#include "commctrl.h"
|
||||
#include "utlsymbol.h"
|
||||
|
||||
class CWorkspace;
|
||||
class CProject;
|
||||
class CScene;
|
||||
class CVCDFile;
|
||||
class CSoundEntry;
|
||||
|
||||
class CSoundList;
|
||||
class CWorkspaceManager;
|
||||
class CSoundFilterTab;
|
||||
class COptionsWindow;
|
||||
|
||||
|
||||
class CSoundBrowser : public mxWindow
|
||||
{
|
||||
typedef mxWindow BaseClass;
|
||||
public:
|
||||
|
||||
CSoundBrowser( mxWindow *parent, CWorkspaceManager *manager, int id );
|
||||
|
||||
virtual int handleEvent( mxEvent *event );
|
||||
virtual void OnDelete();
|
||||
|
||||
CWorkspaceManager *GetManager();
|
||||
|
||||
void RepopulateTree();
|
||||
|
||||
void BuildSelectionList( CUtlVector< CSoundEntry * >& selected );
|
||||
|
||||
void OnPlay();
|
||||
|
||||
void JumpToItem( CSoundEntry *se );
|
||||
|
||||
void OnSearch();
|
||||
|
||||
private:
|
||||
|
||||
char const *GetSearchString();
|
||||
|
||||
void OnShowInWaveBrowser();
|
||||
void OnSoundProperties();
|
||||
void OnAddSound();
|
||||
void OnRemoveSound();
|
||||
void OnGetSentence();
|
||||
void PopulateTree( bool voiceonly, char const *scriptonly );
|
||||
|
||||
void ShowContextMenu( void );
|
||||
|
||||
void LoadAllSounds();
|
||||
void RemoveAllSounds();
|
||||
|
||||
|
||||
CSoundList *m_pListView;
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_BITMAPS = 8,
|
||||
};
|
||||
|
||||
CWorkspaceManager *m_pManager;
|
||||
|
||||
CUtlVector< CSoundEntry * > m_AllSounds;
|
||||
CUtlSymbolTable m_ScriptTable;
|
||||
|
||||
CUtlVector< CUtlSymbol > m_Scripts;
|
||||
|
||||
CSoundFilterTab *m_pFilter;
|
||||
COptionsWindow *m_pOptions;
|
||||
|
||||
CUtlVector< CSoundEntry * > m_CurrentSelection;
|
||||
};
|
||||
|
||||
|
||||
#endif // SOUNDBROWSER_H
|
||||
@@ -0,0 +1,334 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "soundentry.h"
|
||||
#include "sentence.h"
|
||||
#include "iscenemanagersound.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "snd_wave_source.h"
|
||||
#include "cmdlib.h"
|
||||
#include "workspacemanager.h"
|
||||
#include "vcdfile.h"
|
||||
#include "workspacebrowser.h"
|
||||
#include "wavefile.h"
|
||||
#include "wavebrowser.h"
|
||||
#include <vgui/ILocalize.h>
|
||||
#include "tier3/tier3.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *name -
|
||||
//-----------------------------------------------------------------------------
|
||||
CSoundEntry::CSoundEntry( CVCDFile *vcd, char const *name ) : m_pOwner( vcd )
|
||||
{
|
||||
Q_memset( &m_Params, 0, sizeof( m_Params ) );
|
||||
|
||||
m_szScriptFile[ 0 ] = 0;
|
||||
|
||||
Q_strncpy( m_szName, name, sizeof( m_szName ) );
|
||||
|
||||
// Get name out of sound emitter system
|
||||
char filebase [ 64 ];
|
||||
int slot = g_pSoundEmitterSystem->GetSoundIndex( name );
|
||||
if ( g_pSoundEmitterSystem->IsValidIndex( slot ) )
|
||||
{
|
||||
Q_FileBase( g_pSoundEmitterSystem->GetSourceFileForSound( slot ), filebase, sizeof( filebase ) );
|
||||
Q_strncpy( m_szScriptFile, filebase, sizeof( m_szScriptFile ) );
|
||||
|
||||
// Look up and add the .wav files for the sound entry
|
||||
|
||||
CSoundParametersInternal *p = g_pSoundEmitterSystem->InternalGetParametersForSound( slot );
|
||||
if ( p )
|
||||
{
|
||||
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser();
|
||||
Assert( wb );
|
||||
|
||||
int waveCount = p->NumSoundNames();
|
||||
for ( int wave = 0; wave < waveCount; wave++ )
|
||||
{
|
||||
char const *wavname = g_pSoundEmitterSystem->GetWaveName( p->GetSoundNames()[ wave ].symbol );
|
||||
if ( wavname )
|
||||
{
|
||||
CWaveFile *wavefile = wb->FindEntry( wavname, false );
|
||||
if ( wavefile )
|
||||
{
|
||||
AddWave( wavefile );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CSoundEntry::~CSoundEntry()
|
||||
{
|
||||
m_Waves.RemoveAll();
|
||||
}
|
||||
|
||||
CVCDFile *CSoundEntry::GetOwnerVCDFile()
|
||||
{
|
||||
return m_pOwner;
|
||||
}
|
||||
|
||||
int CSoundEntry::GetWaveCount() const
|
||||
{
|
||||
return m_Waves.Count();
|
||||
}
|
||||
|
||||
CWaveFile *CSoundEntry::GetWave( int index )
|
||||
{
|
||||
if ( index < 0 || index >= m_Waves.Count() )
|
||||
return NULL;
|
||||
return m_Waves[ index ];
|
||||
}
|
||||
|
||||
void CSoundEntry::ClearWaves()
|
||||
{
|
||||
m_Waves.RemoveAll();
|
||||
}
|
||||
|
||||
void CSoundEntry::AddWave( CWaveFile *wave )
|
||||
{
|
||||
if ( m_Waves.Find( wave ) != m_Waves.InvalidIndex() )
|
||||
return;
|
||||
|
||||
m_Waves.AddToTail( wave );
|
||||
}
|
||||
|
||||
void CSoundEntry::RemoveWave( CWaveFile *wave )
|
||||
{
|
||||
m_Waves.FindAndRemove( wave );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *wave -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CSoundEntry::FindWave( CWaveFile *wave )
|
||||
{
|
||||
int idx = m_Waves.Find( wave );
|
||||
if ( idx != m_Waves.InvalidIndex() )
|
||||
return idx;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *name -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSoundEntry::SetName( char const *name )
|
||||
{
|
||||
if ( !Q_stricmp( m_szName, name ) )
|
||||
return;
|
||||
|
||||
Q_strncpy( m_szName, name, sizeof( m_szName ) );
|
||||
|
||||
// Get name out of sound emitter system
|
||||
char filebase [ 64 ];
|
||||
int slot = g_pSoundEmitterSystem->GetSoundIndex( name );
|
||||
if ( g_pSoundEmitterSystem->IsValidIndex( slot ) )
|
||||
{
|
||||
Q_FileBase( g_pSoundEmitterSystem->GetSourceFileForSound( slot ), filebase, sizeof( filebase ) );
|
||||
Q_strncpy( m_szScriptFile, filebase, sizeof( m_szScriptFile ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char const *CSoundEntry::GetName() const
|
||||
{
|
||||
return m_szName;
|
||||
}
|
||||
|
||||
void CSoundEntry::ValidateTree( mxTreeView *tree, mxTreeViewItem* parent )
|
||||
{
|
||||
CUtlVector< mxTreeViewItem * > m_KnownItems;
|
||||
|
||||
int c = GetWaveCount();
|
||||
CWaveFile *wave;
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
wave = GetWave( i );
|
||||
if ( !wave )
|
||||
continue;
|
||||
|
||||
char sz[ 256 ];
|
||||
if ( wave->HasLoadedSentenceInfo() )
|
||||
{
|
||||
Q_snprintf( sz, sizeof( sz ), "\"%s\" : '%s'", wave->GetName(), wave->GetSentenceText() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( sz, sizeof( sz ), "\"%s\" : '%s'", wave->GetName(), "(loading...)" );
|
||||
}
|
||||
|
||||
mxTreeViewItem *spot = wave->FindItem( tree, parent );
|
||||
if ( !spot )
|
||||
{
|
||||
spot = tree->add( parent, sz );
|
||||
}
|
||||
|
||||
m_KnownItems.AddToTail( spot );
|
||||
|
||||
wave->SetOrdinal( i );
|
||||
|
||||
tree->setLabel( spot, sz );
|
||||
|
||||
tree->setImages( spot, wave->GetIconIndex(), wave->GetIconIndex() );
|
||||
tree->setUserData( spot, wave );
|
||||
|
||||
wave->ValidateTree( tree, spot );
|
||||
}
|
||||
|
||||
mxTreeViewItem *start = tree->getFirstChild( parent );
|
||||
while ( start )
|
||||
{
|
||||
mxTreeViewItem *next = tree->getNextChild( start );
|
||||
|
||||
if ( m_KnownItems.Find( start ) == m_KnownItems.InvalidIndex() )
|
||||
{
|
||||
tree->remove( start );
|
||||
}
|
||||
|
||||
start = next;
|
||||
}
|
||||
|
||||
tree->sortTree( parent, true, CWorkspaceBrowser::CompareFunc, 0 );
|
||||
}
|
||||
|
||||
void CSoundEntry::Play()
|
||||
{
|
||||
if ( m_Waves.Count() == 0 )
|
||||
return;
|
||||
|
||||
m_nLastPlay = ( m_nLastPlay + 1 ) % m_Waves.Count();
|
||||
|
||||
CWaveFile *wave = GetWave( m_nLastPlay );
|
||||
if ( !wave )
|
||||
return;
|
||||
|
||||
wave->Play();
|
||||
}
|
||||
|
||||
char const *CSoundEntry::GetScriptFile() const
|
||||
{
|
||||
return m_szScriptFile;
|
||||
}
|
||||
|
||||
void CSoundEntry::SetScriptFile( char const *scriptfile )
|
||||
{
|
||||
char filebase [ 64 ];
|
||||
int slot = g_pSoundEmitterSystem->GetSoundIndex( GetName() );
|
||||
Q_FileBase( g_pSoundEmitterSystem->GetSourceFileForSound( slot ), filebase, sizeof( filebase ) );
|
||||
|
||||
if ( !Q_stricmp( GetScriptFile(), filebase ) )
|
||||
return;
|
||||
|
||||
Q_strncpy( m_szScriptFile, filebase, sizeof( m_szScriptFile ) );
|
||||
}
|
||||
|
||||
CSoundParametersInternal *CSoundEntry::GetSoundParameters()
|
||||
{
|
||||
int soundindex = g_pSoundEmitterSystem->GetSoundIndex( GetName() );
|
||||
if ( g_pSoundEmitterSystem->IsValidIndex( soundindex ) )
|
||||
{
|
||||
return g_pSoundEmitterSystem->InternalGetParametersForSound( soundindex );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CSoundEntry::IsCheckedOut() const
|
||||
{
|
||||
// FIXME: This could use the wave state or the script state?
|
||||
return false;
|
||||
}
|
||||
|
||||
int CSoundEntry::GetIconIndex() const
|
||||
{
|
||||
if ( IsCheckedOut() )
|
||||
{
|
||||
return IMAGE_SPEAK_CHECKEDOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IMAGE_SPEAK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSoundEntry::Checkout(bool updatestateicons /*= true*/)
|
||||
{
|
||||
}
|
||||
|
||||
void CSoundEntry::Checkin(bool updatestateicons /*= true*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CSoundEntry::MoveChildUp( ITreeItem *child )
|
||||
{
|
||||
}
|
||||
|
||||
void CSoundEntry::MoveChildDown( ITreeItem *child )
|
||||
{
|
||||
}
|
||||
|
||||
void CSoundEntry::SetDirty( bool dirty )
|
||||
{
|
||||
if ( GetOwnerVCDFile() )
|
||||
{
|
||||
GetOwnerVCDFile()->SetDirty( dirty );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : wavindex -
|
||||
// Output : char const
|
||||
//-----------------------------------------------------------------------------
|
||||
char const *CSoundEntry::GetSentenceText( int wavindex )
|
||||
{
|
||||
if ( !GetWaveCount() )
|
||||
return "";
|
||||
|
||||
CWaveFile *w = GetWave( wavindex );
|
||||
if ( w->HasLoadedSentenceInfo() )
|
||||
{
|
||||
return w->GetSentenceText();
|
||||
}
|
||||
else
|
||||
{
|
||||
return "(loading...)";
|
||||
}
|
||||
}
|
||||
|
||||
void CSoundEntry::GetCCText( wchar_t *out, int maxchars )
|
||||
{
|
||||
out[ 0 ] = 0;
|
||||
|
||||
if ( !g_pVGuiLocalize )
|
||||
return;
|
||||
|
||||
const wchar_t *str = g_pVGuiLocalize->Find( GetName() );
|
||||
if ( !str )
|
||||
return;
|
||||
|
||||
wcsncpy( out, str, maxchars );
|
||||
}
|
||||
|
||||
|
||||
bool CSoundEntry::IsChildFirst( ITreeItem *child )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSoundEntry::IsChildLast( ITreeItem *child )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SOUNDENTRY_H
|
||||
#define SOUNDENTRY_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "itreeitem.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "sentence.h"
|
||||
|
||||
class CAudioSource;
|
||||
class CVCDFile;
|
||||
class CWaveFile;
|
||||
|
||||
class CSoundEntry : public ITreeItem
|
||||
{
|
||||
public:
|
||||
CSoundEntry( CVCDFile *vcd, char const *name );
|
||||
~CSoundEntry();
|
||||
|
||||
CVCDFile *GetOwnerVCDFile();
|
||||
|
||||
void SetName( char const *name );
|
||||
|
||||
char const *GetName() const;
|
||||
|
||||
int GetWaveCount() const;
|
||||
CWaveFile *GetWave( int index );
|
||||
void ClearWaves();
|
||||
void AddWave( CWaveFile *wave );
|
||||
void RemoveWave( CWaveFile *wave );
|
||||
int FindWave( CWaveFile *wave );
|
||||
|
||||
void ValidateTree( mxTreeView *tree, mxTreeViewItem* parent );
|
||||
|
||||
virtual CWorkspace *GetWorkspace() { return NULL; }
|
||||
virtual CProject *GetProject() { return NULL; }
|
||||
virtual CScene *GetScene() { return NULL; }
|
||||
virtual CVCDFile *GetVCDFile() { return NULL; }
|
||||
virtual CSoundEntry *GetSoundEntry() { return this; }
|
||||
virtual CWaveFile *GetWaveFile() { return NULL; }
|
||||
|
||||
void Play();
|
||||
|
||||
char const *GetScriptFile() const;
|
||||
void SetScriptFile( char const *scriptfile );
|
||||
|
||||
char const *GetSentenceText( int wavindex );
|
||||
void GetCCText( wchar_t *out, int maxchars );
|
||||
|
||||
CSoundParametersInternal *GetSoundParameters();
|
||||
|
||||
virtual void Checkout( bool updatestateicons = true );
|
||||
virtual void Checkin( bool updatestateicons = true );
|
||||
|
||||
bool IsCheckedOut() const;
|
||||
int GetIconIndex() const;
|
||||
|
||||
|
||||
virtual void MoveChildUp( ITreeItem *child );
|
||||
virtual void MoveChildDown( ITreeItem *child );
|
||||
|
||||
virtual void SetDirty( bool dirty );
|
||||
|
||||
virtual bool IsChildFirst( ITreeItem *child );
|
||||
virtual bool IsChildLast( ITreeItem *child );
|
||||
|
||||
private:
|
||||
|
||||
CSoundParameters m_Params;
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_SOUND_NAME = 256,
|
||||
MAX_SCRIPT_FILE = 64,
|
||||
MAX_SOUND_FILENAME = 128,
|
||||
};
|
||||
|
||||
char m_szName[ MAX_SOUND_NAME ];
|
||||
char m_szScriptFile[ MAX_SCRIPT_FILE ];
|
||||
|
||||
CVCDFile *m_pOwner;
|
||||
|
||||
CUtlVector< CWaveFile * > m_Waves;
|
||||
|
||||
int m_nLastPlay;
|
||||
};
|
||||
|
||||
#endif // SOUNDENTRY_H
|
||||
@@ -0,0 +1,616 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include <mxtk/mx.h>
|
||||
#include <stdio.h>
|
||||
#include "resource.h"
|
||||
#include "SoundProperties.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "soundentry.h"
|
||||
#include "cmdlib.h"
|
||||
#include "workspacemanager.h"
|
||||
#include "wavebrowser.h"
|
||||
#include "wavefile.h"
|
||||
#include "waveproperties.h"
|
||||
|
||||
static CSoundParams g_Params;
|
||||
|
||||
static void PopulateChannelList( HWND wnd, CSoundParametersInternal *p )
|
||||
{
|
||||
HWND control = GetDlgItem( wnd, IDC_CHANNEL );
|
||||
if ( !control )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage( control, CB_RESETCONTENT, 0, 0 );
|
||||
if ( p )
|
||||
{
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)p->ChannelToString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)"CHAN_VOICE" );
|
||||
}
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_VOICE" );
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_AUTO" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_WEAPON" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_ITEM" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_BODY" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_STREAM" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_STATIC" );
|
||||
}
|
||||
|
||||
static void PopulateVolumeList( HWND wnd, CSoundParametersInternal *p )
|
||||
{
|
||||
HWND control = GetDlgItem( wnd, IDC_VOLUME );
|
||||
if ( !control )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage( control, CB_RESETCONTENT, 0, 0 );
|
||||
|
||||
if ( p )
|
||||
{
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)p->VolumeToString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)"VOL_NORM" );
|
||||
}
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"VOL_NORM" );
|
||||
}
|
||||
|
||||
static void PopulateSoundlevelList( HWND wnd, CSoundParametersInternal *p )
|
||||
{
|
||||
HWND control = GetDlgItem( wnd, IDC_SOUNDLEVEL );
|
||||
if ( !control )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage( control, CB_RESETCONTENT, 0, 0 );
|
||||
|
||||
if ( p )
|
||||
{
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)p->SoundLevelToString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)"SNDLVL_NORM" );
|
||||
}
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_NORM" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_NONE" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_IDLE" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_TALKING" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_STATIC" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_GUNFIRE" );
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_25dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_30dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_35dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_40dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_45dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_50dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_55dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_60dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_65dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_70dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_75dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_80dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_85dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_90dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_95dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_100dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_105dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_120dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_130dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_140dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_150dB" );
|
||||
}
|
||||
|
||||
static void PopulatePitchList( HWND wnd, CSoundParametersInternal *p )
|
||||
{
|
||||
HWND control = GetDlgItem( wnd, IDC_PITCH );
|
||||
if ( !control )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage( control, CB_RESETCONTENT, 0, 0 );
|
||||
|
||||
if ( p )
|
||||
{
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)p->PitchToString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)"PITCH_NORM" );
|
||||
}
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"PITCH_NORM" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"PITCH_LOW" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"PITCH_HIGH" );
|
||||
}
|
||||
|
||||
|
||||
static void PopulateScriptList( HWND wnd, char const *curscript )
|
||||
{
|
||||
HWND control = GetDlgItem( wnd, IDC_SOUNDSCRIPT );
|
||||
if ( !control )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage( control, CB_RESETCONTENT, 0, 0 );
|
||||
|
||||
if ( curscript )
|
||||
{
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)curscript );
|
||||
}
|
||||
|
||||
int c = g_pSoundEmitterSystem->GetNumSoundScripts();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
// add text to combo box
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)g_pSoundEmitterSystem->GetSoundScriptName( i ) );
|
||||
|
||||
if ( !curscript && i == 0 )
|
||||
{
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)g_pSoundEmitterSystem->GetSoundScriptName( i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool WaveLessFunc( const char *const& name1, const char *const& name2 )
|
||||
{
|
||||
if ( stricmp( name1, name2 ) < 0 )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : wnd -
|
||||
// Output : static void
|
||||
//-----------------------------------------------------------------------------
|
||||
static void PopulateWaveList( HWND wnd, CSoundParametersInternal *p )
|
||||
{
|
||||
HWND control = GetDlgItem( wnd, IDC_WAVELIST );
|
||||
if ( !control )
|
||||
return;
|
||||
|
||||
// Remove all
|
||||
SendMessage( control, LB_RESETCONTENT, 0, 0 );
|
||||
|
||||
if ( !p )
|
||||
return;
|
||||
|
||||
CUtlRBTree< char const *, int > m_SortedNames( 0, 0, WaveLessFunc );
|
||||
|
||||
int c = p->NumSoundNames();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
char const *name = strdup( g_pSoundEmitterSystem->GetWaveName( p->GetSoundNames()[ i ].symbol ) );
|
||||
|
||||
m_SortedNames.Insert( name );
|
||||
}
|
||||
|
||||
int j = m_SortedNames.FirstInorder();
|
||||
while ( j != m_SortedNames.InvalidIndex() )
|
||||
{
|
||||
char const *name = m_SortedNames[ j ];
|
||||
if ( name && name[ 0 ] )
|
||||
{
|
||||
SendMessage( control, LB_ADDSTRING, 0, (LPARAM)name );
|
||||
}
|
||||
|
||||
delete name;
|
||||
|
||||
j = m_SortedNames.NextInorder( j );
|
||||
}
|
||||
}
|
||||
|
||||
static void PopulateWaveList_Available( HWND wnd )
|
||||
{
|
||||
HWND control = GetDlgItem( wnd, IDC_WAVELIST_AVAILABLE );
|
||||
if ( !control )
|
||||
return;
|
||||
|
||||
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser();
|
||||
if ( !wb )
|
||||
{
|
||||
Assert( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
CUtlRBTree< char const *, int > m_SortedNames( 0, 0, WaveLessFunc );
|
||||
|
||||
int c = wb->GetSoundCount();;
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
CWaveFile *entry = wb->GetSound( i );
|
||||
if ( !entry )
|
||||
continue;
|
||||
|
||||
char const *name = entry->GetName();
|
||||
m_SortedNames.Insert( name );
|
||||
}
|
||||
|
||||
// Remove all
|
||||
SendMessage( control, LB_RESETCONTENT, 0, 0 );
|
||||
|
||||
int j = m_SortedNames.FirstInorder();
|
||||
while ( j != m_SortedNames.InvalidIndex() )
|
||||
{
|
||||
char const *name = m_SortedNames[ j ];
|
||||
if ( name && name[ 0 ] )
|
||||
{
|
||||
SendMessage( control, LB_ADDSTRING, 0, (LPARAM)name );
|
||||
}
|
||||
|
||||
j = m_SortedNames.NextInorder( j );
|
||||
}
|
||||
}
|
||||
|
||||
static void SoundProperties_GetSelectedWaveList( HWND hwndDlg, HWND control, CUtlVector< int >& list )
|
||||
{
|
||||
if ( !control )
|
||||
return;
|
||||
|
||||
int count = SendMessage( control, LB_GETSELCOUNT, 0, 0 );
|
||||
if ( count == LB_ERR )
|
||||
return;
|
||||
|
||||
int *s = new int[ count ];
|
||||
|
||||
SendMessage( control, LB_GETSELITEMS, count, (LPARAM)s );
|
||||
|
||||
for ( int i = 0 ;i < count; i++ )
|
||||
{
|
||||
list.AddToTail( s[ i ] );
|
||||
}
|
||||
|
||||
delete[] s;
|
||||
}
|
||||
|
||||
static const char *SoundProperties_GetSelectedWave( HWND hwndDlg, HWND control, int *item = NULL )
|
||||
{
|
||||
if ( item )
|
||||
*item = -1;
|
||||
|
||||
if ( !control )
|
||||
return NULL;
|
||||
|
||||
int selectedionindex = SendMessage( control, LB_GETCURSEL, 0, 0 );
|
||||
if ( selectedionindex == LB_ERR )
|
||||
return NULL;
|
||||
|
||||
static char itemtext[ 256 ];
|
||||
SendMessage( control, LB_GETTEXT, selectedionindex, (LPARAM)itemtext );
|
||||
|
||||
if ( item )
|
||||
{
|
||||
*item = selectedionindex;
|
||||
}
|
||||
|
||||
return itemtext;
|
||||
}
|
||||
|
||||
static void SoundProperties_OnOK( HWND hwndDlg )
|
||||
{
|
||||
CSoundParametersInternal outparams;
|
||||
|
||||
// Gather info and make changes
|
||||
CSoundEntry *item = g_Params.items[ 0 ];
|
||||
|
||||
int soundindex = -1;
|
||||
char const *script = NULL;
|
||||
|
||||
char outsoundname[ 256 ];
|
||||
char outscriptfile[ 256 ];
|
||||
|
||||
GetDlgItemText( hwndDlg, IDC_SOUNDNAME, outsoundname, sizeof( outsoundname ) );
|
||||
GetDlgItemText( hwndDlg, IDC_SOUNDSCRIPT, outscriptfile, sizeof( outscriptfile ) );
|
||||
|
||||
if ( !g_Params.addsound )
|
||||
{
|
||||
soundindex = g_pSoundEmitterSystem->GetSoundIndex( item->GetName() );
|
||||
script = g_pSoundEmitterSystem->GetSourceFileForSound( soundindex );
|
||||
}
|
||||
|
||||
char sz[ 128 ];
|
||||
GetDlgItemText( hwndDlg, IDC_CHANNEL, sz, sizeof( sz ) );
|
||||
outparams.ChannelFromString( sz );
|
||||
|
||||
GetDlgItemText( hwndDlg, IDC_VOLUME, sz, sizeof( sz ) );
|
||||
outparams.VolumeFromString( sz );
|
||||
|
||||
GetDlgItemText( hwndDlg, IDC_SOUNDLEVEL, sz, sizeof( sz ) );
|
||||
outparams.SoundLevelFromString( sz );
|
||||
|
||||
GetDlgItemText( hwndDlg, IDC_PITCH, sz, sizeof( sz ) );
|
||||
outparams.PitchFromString( sz );
|
||||
|
||||
bool owneronly = SendMessage( GetDlgItem( hwndDlg, IDC_OWNERONLY ), BM_GETCHECK, 0, 0 ) == BST_CHECKED ? true : false;
|
||||
|
||||
outparams.SetOnlyPlayToOwner( owneronly );
|
||||
|
||||
// Retrieve wave list
|
||||
int c = SendMessage( GetDlgItem( hwndDlg, IDC_WAVELIST ), LB_GETCOUNT, 0, 0 );
|
||||
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
char wavename[ 256 ];
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_WAVELIST ), LB_GETTEXT, i, (LPARAM)wavename );
|
||||
|
||||
CUtlSymbol sym = g_pSoundEmitterSystem->AddWaveName( wavename );
|
||||
SoundFile sf;
|
||||
sf.symbol = sym;
|
||||
sf.gender = GENDER_NONE;
|
||||
outparams.AddSoundName( sf );
|
||||
}
|
||||
|
||||
if ( g_Params.addsound )
|
||||
{
|
||||
g_pSoundEmitterSystem->AddSound( outsoundname, outscriptfile, outparams );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update sound stuff
|
||||
g_pSoundEmitterSystem->MoveSound( item->GetName(), outscriptfile );
|
||||
item->SetScriptFile( outscriptfile );
|
||||
g_pSoundEmitterSystem->UpdateSoundParameters( item->GetName(), outparams );
|
||||
// Rename if necessary
|
||||
g_pSoundEmitterSystem->RenameSound( item->GetName(), outsoundname );
|
||||
}
|
||||
|
||||
// Apply changes
|
||||
item->SetName( outsoundname );
|
||||
|
||||
// Repopulate things
|
||||
GetWorkspaceManager()->RefreshBrowsers();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : hwndDlg -
|
||||
// uMsg -
|
||||
// wParam -
|
||||
// lParam -
|
||||
// Output : static BOOL CALLBACK
|
||||
//-----------------------------------------------------------------------------
|
||||
static BOOL CALLBACK SoundPropertiesDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
g_Params.PositionSelf( hwndDlg );
|
||||
|
||||
CSoundEntry *item = NULL;
|
||||
|
||||
CSoundParametersInternal *p = NULL;
|
||||
char const *script = NULL;
|
||||
|
||||
if ( g_Params.addsound )
|
||||
{
|
||||
Assert( g_Params.items.Count() == 0 );
|
||||
|
||||
CSoundEntry *entry = new CSoundEntry( NULL, "Unnamed" );
|
||||
g_Params.items.AddToTail( entry );
|
||||
|
||||
item = item = g_Params.items[ 0 ];
|
||||
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_OWNERONLY ), BM_SETCHECK,
|
||||
( WPARAM )BST_UNCHECKED,
|
||||
( LPARAM )0 );
|
||||
|
||||
SetDlgItemText( hwndDlg, IDC_STATIC_SENTENCETEXT, "" );
|
||||
SetDlgItemTextW( hwndDlg, IDC_STATIC_CLOSECAPTION, L"" );
|
||||
}
|
||||
else
|
||||
{
|
||||
item = g_Params.items[ 0 ];
|
||||
|
||||
int soundindex = g_pSoundEmitterSystem->GetSoundIndex( item->GetName() );
|
||||
|
||||
script = g_pSoundEmitterSystem->GetSourceFileForSound( soundindex );
|
||||
|
||||
p = g_pSoundEmitterSystem->InternalGetParametersForSound( soundindex );
|
||||
Assert( p );
|
||||
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_OWNERONLY ), BM_SETCHECK,
|
||||
( WPARAM ) p->OnlyPlayToOwner() ? BST_CHECKED : BST_UNCHECKED,
|
||||
( LPARAM )0 );
|
||||
|
||||
SetDlgItemText( hwndDlg, IDC_STATIC_SENTENCETEXT, item->GetSentenceText( 0 ) );
|
||||
wchar_t cctext[ 1024 ];
|
||||
item->GetCCText( cctext, sizeof( cctext ) / sizeof( wchar_t ) );
|
||||
|
||||
SetDlgItemTextW( hwndDlg, IDC_STATIC_CLOSECAPTION, cctext );
|
||||
}
|
||||
|
||||
PopulateChannelList( hwndDlg, p );
|
||||
PopulateVolumeList( hwndDlg, p );
|
||||
PopulateSoundlevelList( hwndDlg, p );
|
||||
PopulatePitchList( hwndDlg, p );
|
||||
|
||||
PopulateWaveList( hwndDlg, p );
|
||||
|
||||
SetDlgItemText( hwndDlg, IDC_SOUNDNAME, item->GetName() );
|
||||
|
||||
PopulateScriptList( hwndDlg, script );
|
||||
|
||||
PopulateWaveList_Available( hwndDlg );
|
||||
|
||||
SetWindowText( hwndDlg, g_Params.m_szDialogTitle );
|
||||
|
||||
SetFocus( GetDlgItem( hwndDlg, IDC_SOUNDNAME ) );
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
{
|
||||
SoundProperties_OnOK( hwndDlg );
|
||||
|
||||
EndDialog( hwndDlg, 1 );
|
||||
}
|
||||
break;
|
||||
case IDCANCEL:
|
||||
EndDialog( hwndDlg, 0 );
|
||||
break;
|
||||
case IDC_WAVELIST:
|
||||
{
|
||||
if ( HIWORD(wParam) == LBN_SELCHANGE )
|
||||
{
|
||||
// Find selected item in wave list...
|
||||
char const *wave = SoundProperties_GetSelectedWave( hwndDlg, GetDlgItem( hwndDlg, IDC_WAVELIST ) );
|
||||
if ( wave )
|
||||
{
|
||||
// Look it up
|
||||
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser();
|
||||
if ( wb )
|
||||
{
|
||||
CWaveFile *wavefile = wb->FindEntry( wave, true );
|
||||
if ( wavefile )
|
||||
{
|
||||
SetDlgItemText( hwndDlg, IDC_STATIC_SENTENCETEXT, wavefile->GetSentenceText() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDC_WAVEPROPERTIES:
|
||||
{
|
||||
// Find selected item in wave list...
|
||||
char const *wave = SoundProperties_GetSelectedWave( hwndDlg, GetDlgItem( hwndDlg, IDC_WAVELIST ) );
|
||||
if ( wave )
|
||||
{
|
||||
// Look it up
|
||||
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser();
|
||||
if ( wb )
|
||||
{
|
||||
CWaveFile *wavefile = wb->FindEntry( wave, true );
|
||||
if ( wavefile )
|
||||
{
|
||||
CWaveParams wp;
|
||||
memset( &wp, 0, sizeof( wp ) );
|
||||
|
||||
Q_snprintf( wp.m_szDialogTitle, sizeof( wp.m_szDialogTitle ), "Wave Properties" );
|
||||
|
||||
wp.items.AddToTail( wavefile );
|
||||
|
||||
WaveProperties( &wp );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDC_REMOVEWAVE:
|
||||
{
|
||||
CUtlVector<int> selected;
|
||||
SoundProperties_GetSelectedWaveList( hwndDlg, GetDlgItem( hwndDlg, IDC_WAVELIST ), selected );
|
||||
int count = selected.Count();
|
||||
if ( count >= 1 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
char wavename[ 256 ];
|
||||
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_WAVELIST), LB_GETTEXT, selected[ i ], (LPARAM)wavename );
|
||||
|
||||
// Add it to global parameters, too
|
||||
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser();
|
||||
if ( wb )
|
||||
{
|
||||
CWaveFile *wavefile = wb->FindEntry( wavename, true );
|
||||
if ( wavefile )
|
||||
{
|
||||
CSoundEntry *item = g_Params.items[ 0 ];
|
||||
item->RemoveWave( wavefile );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = count - 1; i >= 0; i-- )
|
||||
{
|
||||
// Remove them from list
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_WAVELIST), LB_DELETESTRING, selected[ i ], 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDC_ADDWAVE:
|
||||
{
|
||||
CUtlVector<int> selected;
|
||||
SoundProperties_GetSelectedWaveList( hwndDlg, GetDlgItem( hwndDlg, IDC_WAVELIST_AVAILABLE ), selected );
|
||||
int count = selected.Count();
|
||||
if ( count >= 1 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
char wavename[ 256 ];
|
||||
|
||||
// Get selection wave name
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_WAVELIST_AVAILABLE), LB_GETTEXT, selected[ i ], (LPARAM)wavename );
|
||||
|
||||
// Add it to global parameters, too
|
||||
CWaveBrowser *wb = GetWorkspaceManager()->GetWaveBrowser();
|
||||
if ( wb )
|
||||
{
|
||||
CWaveFile *wavefile = wb->FindEntry( wavename, true );
|
||||
if ( wavefile )
|
||||
{
|
||||
CSoundEntry *item = g_Params.items[ 0 ];
|
||||
if ( item->FindWave( wavefile ) == -1 )
|
||||
{
|
||||
item->AddWave( wavefile );
|
||||
// Add it to list
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_WAVELIST ), LB_ADDSTRING, 0, (LPARAM)wavename );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *view -
|
||||
// *actor -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int SoundProperties( CSoundParams *params )
|
||||
{
|
||||
g_Params = *params;
|
||||
|
||||
int retval = DialogBox( (HINSTANCE)GetModuleHandle( 0 ),
|
||||
MAKEINTRESOURCE( IDD_SOUNDPROPERTIES ),
|
||||
(HWND)GetWorkspaceManager()->getHandle(),
|
||||
(DLGPROC)SoundPropertiesDialogProc );
|
||||
|
||||
*params = g_Params;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SOUNDPROPERTIES_H
|
||||
#define SOUNDPROPERTIES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basedialogparams.h"
|
||||
|
||||
class CSoundEntry;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CSoundParams : public CBaseDialogParams
|
||||
{
|
||||
bool addsound;
|
||||
|
||||
CSoundParams()
|
||||
{
|
||||
}
|
||||
|
||||
CSoundParams( const CSoundParams& src )
|
||||
{
|
||||
addsound = src.addsound;
|
||||
|
||||
int c = src.items.Count();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
items.AddToTail( src.items[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
CUtlVector< CSoundEntry * > items;
|
||||
};
|
||||
|
||||
int SoundProperties( CSoundParams *params );
|
||||
|
||||
#endif // SOUNDPROPERTIES_H
|
||||
@@ -0,0 +1,240 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include <mxtk/mx.h>
|
||||
#include <stdio.h>
|
||||
#include "resource.h"
|
||||
#include "SoundProperties_Multiple.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "soundentry.h"
|
||||
#include "cmdlib.h"
|
||||
#include "workspacemanager.h"
|
||||
#include "wavebrowser.h"
|
||||
#include "wavefile.h"
|
||||
#include "waveproperties.h"
|
||||
|
||||
static CSoundParams g_Params;
|
||||
|
||||
static void PopulateChannelList( HWND wnd, CSoundParametersInternal *p )
|
||||
{
|
||||
HWND control = GetDlgItem( wnd, IDC_CHANNEL );
|
||||
if ( !control )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage( control, CB_RESETCONTENT, 0, 0 );
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)p->ChannelToString() );
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_VOICE" );
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_AUTO" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_WEAPON" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_ITEM" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_BODY" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_STREAM" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"CHAN_STATIC" );
|
||||
}
|
||||
|
||||
static void PopulateVolumeList( HWND wnd, CSoundParametersInternal *p )
|
||||
{
|
||||
HWND control = GetDlgItem( wnd, IDC_VOLUME );
|
||||
if ( !control )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage( control, CB_RESETCONTENT, 0, 0 );
|
||||
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)p->VolumeToString() );
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"VOL_NORM" );
|
||||
}
|
||||
|
||||
static void PopulateSoundlevelList( HWND wnd, CSoundParametersInternal *p )
|
||||
{
|
||||
HWND control = GetDlgItem( wnd, IDC_SOUNDLEVEL );
|
||||
if ( !control )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage( control, CB_RESETCONTENT, 0, 0 );
|
||||
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)p->SoundLevelToString() );
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_NORM" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_NONE" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_IDLE" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_TALKING" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_STATIC" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_GUNFIRE" );
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_25dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_30dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_35dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_40dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_45dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_50dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_55dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_60dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_65dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_70dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_75dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_80dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_85dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_90dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_95dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_100dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_105dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_120dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_130dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_140dB" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"SNDLVL_150dB" );
|
||||
}
|
||||
|
||||
static void PopulatePitchList( HWND wnd, CSoundParametersInternal *p )
|
||||
{
|
||||
HWND control = GetDlgItem( wnd, IDC_PITCH );
|
||||
if ( !control )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage( control, CB_RESETCONTENT, 0, 0 );
|
||||
|
||||
SendMessage( control, WM_SETTEXT , 0, (LPARAM)p->PitchToString() );
|
||||
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"PITCH_NORM" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"PITCH_LOW" );
|
||||
SendMessage( control, CB_ADDSTRING, 0, (LPARAM)"PITCH_HIGH" );
|
||||
}
|
||||
|
||||
static void SoundProperties_Multiple_OnOK( HWND hwndDlg )
|
||||
{
|
||||
int c = g_Params.items.Count();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
// Gather info and make changes
|
||||
CSoundEntry *item = g_Params.items[ i ];
|
||||
Assert( item );
|
||||
if ( !item )
|
||||
continue;
|
||||
|
||||
int idx = g_pSoundEmitterSystem->GetSoundIndex( item->GetName() );
|
||||
if ( !g_pSoundEmitterSystem->IsValidIndex( idx ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
CSoundParametersInternal *baseparams = g_pSoundEmitterSystem->InternalGetParametersForSound( idx );
|
||||
if ( !baseparams )
|
||||
return;
|
||||
|
||||
// Start with old settings
|
||||
CSoundParametersInternal outparams;
|
||||
outparams.CopyFrom( *baseparams );
|
||||
|
||||
char sz[ 128 ];
|
||||
GetDlgItemText( hwndDlg, IDC_CHANNEL, sz, sizeof( sz ) );
|
||||
outparams.ChannelFromString( sz );
|
||||
|
||||
GetDlgItemText( hwndDlg, IDC_VOLUME, sz, sizeof( sz ) );
|
||||
outparams.VolumeFromString( sz );
|
||||
|
||||
GetDlgItemText( hwndDlg, IDC_SOUNDLEVEL, sz, sizeof( sz ) );
|
||||
outparams.SoundLevelFromString( sz );
|
||||
|
||||
GetDlgItemText( hwndDlg, IDC_PITCH, sz, sizeof( sz ) );
|
||||
outparams.PitchFromString( sz );
|
||||
|
||||
bool owneronly = SendMessage( GetDlgItem( hwndDlg, IDC_OWNERONLY ), BM_GETCHECK, 0, 0 ) == BST_CHECKED ? true : false;
|
||||
|
||||
outparams.SetOnlyPlayToOwner( owneronly );
|
||||
|
||||
g_pSoundEmitterSystem->UpdateSoundParameters( item->GetName(), outparams );
|
||||
}
|
||||
|
||||
// Repopulate things
|
||||
GetWorkspaceManager()->RefreshBrowsers();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : hwndDlg -
|
||||
// uMsg -
|
||||
// wParam -
|
||||
// lParam -
|
||||
// Output : static BOOL CALLBACK
|
||||
//-----------------------------------------------------------------------------
|
||||
static BOOL CALLBACK SoundProperties_MultipleDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
g_Params.PositionSelf( hwndDlg );
|
||||
|
||||
CSoundEntry *entry = g_Params.items[ 0 ];
|
||||
Assert( entry );
|
||||
|
||||
CSoundParametersInternal *p = entry->GetSoundParameters();
|
||||
Assert( p );
|
||||
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_OWNERONLY ), BM_SETCHECK,
|
||||
( WPARAM ) p->OnlyPlayToOwner() ? BST_CHECKED : BST_UNCHECKED,
|
||||
( LPARAM )0 );
|
||||
|
||||
PopulateChannelList( hwndDlg, p );
|
||||
PopulateVolumeList( hwndDlg, p );
|
||||
PopulateSoundlevelList( hwndDlg, p );
|
||||
PopulatePitchList( hwndDlg, p );
|
||||
|
||||
SetWindowText( hwndDlg, g_Params.m_szDialogTitle );
|
||||
|
||||
SetFocus( GetDlgItem( hwndDlg, IDC_CHANNEL ) );
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
{
|
||||
SoundProperties_Multiple_OnOK( hwndDlg );
|
||||
|
||||
EndDialog( hwndDlg, 1 );
|
||||
}
|
||||
break;
|
||||
case IDCANCEL:
|
||||
EndDialog( hwndDlg, 0 );
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *view -
|
||||
// *actor -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int SoundProperties_Multiple( CSoundParams *params )
|
||||
{
|
||||
g_Params = *params;
|
||||
|
||||
int retval = DialogBox( (HINSTANCE)GetModuleHandle( 0 ),
|
||||
MAKEINTRESOURCE( IDD_SOUNDPROPERTIES_MULTIPLE ),
|
||||
(HWND)GetWorkspaceManager()->getHandle(),
|
||||
(DLGPROC)SoundProperties_MultipleDialogProc );
|
||||
|
||||
*params = g_Params;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SOUNDPROPERTIES_MULTIPLE_H
|
||||
#define SOUNDPROPERTIES_MULTIPLE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basedialogparams.h"
|
||||
#include "soundproperties.h"
|
||||
|
||||
class CSoundEntry;
|
||||
|
||||
int SoundProperties_Multiple( CSoundParams *params );
|
||||
|
||||
#endif // SOUNDPROPERTIES_MULTIPLE_H
|
||||
@@ -0,0 +1,245 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "statuswindow.h"
|
||||
#include "drawhelper.h"
|
||||
|
||||
CStatusWindow *g_pStatusWindow = NULL;
|
||||
|
||||
#define STATUS_SCROLLBAR_SIZE 12
|
||||
#define STATUS_FONT_SIZE 10
|
||||
|
||||
CStatusWindow::CStatusWindow(mxWindow *parent, int x, int y, int w, int h, const char *label /*= 0*/ )
|
||||
: mxWindow( parent, x, y, w, h, label ), m_pScrollbar(NULL)
|
||||
{
|
||||
for ( int i = 0; i < MAX_TEXT_LINES; i++ )
|
||||
{
|
||||
m_rgTextLines[ i ].m_szText[ 0 ] = 0;
|
||||
m_rgTextLines[ i ].r = CONSOLE_R;
|
||||
m_rgTextLines[ i ].g = CONSOLE_G;
|
||||
m_rgTextLines[ i ].b = CONSOLE_B;
|
||||
m_rgTextLines[ i ].curtime = 0;
|
||||
}
|
||||
m_nCurrentLine = 0;
|
||||
|
||||
m_pScrollbar = new mxScrollbar( this, 0, 0, STATUS_SCROLLBAR_SIZE, 100, IDC_STATUS_SCROLL, mxScrollbar::Vertical );
|
||||
m_pScrollbar->setRange( 0, 1000 );
|
||||
m_pScrollbar->setPagesize( 100 );
|
||||
g_pStatusWindow = this;
|
||||
}
|
||||
|
||||
CStatusWindow::~CStatusWindow()
|
||||
{
|
||||
g_pStatusWindow = NULL;
|
||||
}
|
||||
|
||||
void CStatusWindow::redraw()
|
||||
{
|
||||
// if ( !ToolCanDraw() )
|
||||
// return;
|
||||
|
||||
if ( !m_pScrollbar )
|
||||
return;
|
||||
|
||||
CDrawHelper helper( this, RGB( 0, 0, 0 ) );
|
||||
|
||||
RECT rc;
|
||||
helper.GetClientRect( rc );
|
||||
|
||||
RECT rcText = rc;
|
||||
|
||||
int lineheight = ( STATUS_FONT_SIZE + 2 );
|
||||
|
||||
InflateRect( &rcText, -4, 0 );
|
||||
rcText.bottom = h2() - 4;
|
||||
rcText.top = rcText.bottom - lineheight;
|
||||
|
||||
// int minval = m_pScrollbar->getMinValue();
|
||||
int maxval = m_pScrollbar->getMaxValue();
|
||||
int pagesize = m_pScrollbar->getPagesize();
|
||||
int curval = m_pScrollbar->getValue();
|
||||
|
||||
int offset = ( maxval - pagesize ) - curval;
|
||||
offset = ( offset + lineheight - 1 ) / lineheight;
|
||||
|
||||
offset = max( 0, offset );
|
||||
//offset = 0;
|
||||
//offset += 10;
|
||||
//offset = max( 0, offset );
|
||||
|
||||
for ( int i = 0; i < MAX_TEXT_LINES - offset; i++ )
|
||||
{
|
||||
int rawline = m_nCurrentLine - i - 1;
|
||||
if ( rawline <= 0 )
|
||||
continue;
|
||||
|
||||
if ( rcText.bottom < 0 )
|
||||
break;
|
||||
|
||||
int line = ( rawline - offset ) & TEXT_LINE_MASK;
|
||||
|
||||
COLORREF clr = RGB( m_rgTextLines[ line ].r, m_rgTextLines[ line ].g, m_rgTextLines[ line ].b );
|
||||
|
||||
char *ptext = m_rgTextLines[ line ].m_szText;
|
||||
|
||||
RECT rcTime = rcText;
|
||||
rcTime.right = rcTime.left + 50;
|
||||
|
||||
char sz[ 32 ];
|
||||
sprintf( sz, "%.3f", m_rgTextLines[ line ].curtime );
|
||||
|
||||
int len = helper.CalcTextWidth( "Arial", STATUS_FONT_SIZE, FW_NORMAL, sz );
|
||||
|
||||
rcTime.left = rcTime.right - len - 5;
|
||||
|
||||
helper.DrawColoredText( "Arial", STATUS_FONT_SIZE, FW_NORMAL, RGB( 255, 255, 150 ), rcTime, sz );
|
||||
|
||||
rcTime = rcText;
|
||||
rcTime.left += 50;
|
||||
|
||||
helper.DrawColoredText( "Arial", STATUS_FONT_SIZE, FW_NORMAL, clr, rcTime, ptext );
|
||||
|
||||
OffsetRect( &rcText, 0, -lineheight );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CStatusWindow::PaintBackground( void )
|
||||
{
|
||||
redraw();
|
||||
return false;
|
||||
}
|
||||
|
||||
void CStatusWindow::StatusPrint( int r, int g, int b, bool overwrite, const char *text )
|
||||
{
|
||||
float curtime = (float)Plat_FloatTime();
|
||||
|
||||
char sz[32];
|
||||
sprintf( sz, "%.3f ", curtime );
|
||||
|
||||
OutputDebugString( sz );
|
||||
OutputDebugString( text );
|
||||
|
||||
char fixedtext[ 512 ];
|
||||
char *in, *out;
|
||||
in = (char *)text;
|
||||
out = fixedtext;
|
||||
|
||||
int c = 0;
|
||||
while ( *in && c < 511 )
|
||||
{
|
||||
if ( *in == '\n' || *in == '\r' )
|
||||
{
|
||||
in++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out++ = *in++;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
|
||||
if ( overwrite )
|
||||
{
|
||||
m_nCurrentLine--;
|
||||
}
|
||||
|
||||
int i = m_nCurrentLine & TEXT_LINE_MASK;
|
||||
|
||||
strncpy( m_rgTextLines[ i ].m_szText, fixedtext, 511 );
|
||||
m_rgTextLines[ i ].m_szText[ 511 ] = 0;
|
||||
|
||||
m_rgTextLines[ i ].r = r;
|
||||
m_rgTextLines[ i ].g = g;
|
||||
m_rgTextLines[ i ].b = b;
|
||||
m_rgTextLines[ i ].curtime = curtime;
|
||||
|
||||
m_nCurrentLine++;
|
||||
|
||||
if ( m_nCurrentLine <= MAX_TEXT_LINES )
|
||||
{
|
||||
PositionSliders( 0 );
|
||||
}
|
||||
m_pScrollbar->setValue( m_pScrollbar->getMaxValue() );
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : sboffset -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStatusWindow::PositionSliders( int sboffset )
|
||||
{
|
||||
int lineheight = ( STATUS_FONT_SIZE + 2 );
|
||||
|
||||
int linesused = min( (int)MAX_TEXT_LINES, m_nCurrentLine );
|
||||
linesused = max( linesused, 1 );
|
||||
|
||||
int trueh = h2();
|
||||
|
||||
int vpixelsneeded = max( linesused * lineheight, trueh );
|
||||
m_pScrollbar->setVisible( linesused * lineheight > trueh );
|
||||
|
||||
|
||||
m_pScrollbar->setPagesize( trueh );
|
||||
m_pScrollbar->setRange( 0, vpixelsneeded );
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *event -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CStatusWindow::handleEvent( mxEvent *event )
|
||||
{
|
||||
int iret = 0;
|
||||
|
||||
switch ( event->event )
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case mxEvent::Size:
|
||||
{
|
||||
m_pScrollbar->setBounds( w2() - STATUS_SCROLLBAR_SIZE, 0, STATUS_SCROLLBAR_SIZE, h2() );
|
||||
PositionSliders( 0 );
|
||||
m_pScrollbar->setValue( m_pScrollbar->getMaxValue() );
|
||||
iret = 1;
|
||||
}
|
||||
break;
|
||||
case mxEvent::Action:
|
||||
{
|
||||
iret = 1;
|
||||
switch ( event->action )
|
||||
{
|
||||
default:
|
||||
iret = 0;
|
||||
break;
|
||||
case IDC_STATUS_SCROLL:
|
||||
{
|
||||
if ( event->event == mxEvent::Action &&
|
||||
event->modifiers == SB_THUMBTRACK)
|
||||
{
|
||||
int offset = event->height;
|
||||
m_pScrollbar->setValue( offset );
|
||||
PositionSliders( offset );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return iret;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef STATUSWINDOW_H
|
||||
#define STATUSWINDOW_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class mxScrollbar;
|
||||
|
||||
#define IDC_STATUS_SCROLL 1000
|
||||
|
||||
class CStatusWindow : public mxWindow
|
||||
{
|
||||
public:
|
||||
CStatusWindow (mxWindow *parent, int x, int y, int w, int h, const char *label = 0 );
|
||||
~CStatusWindow();
|
||||
|
||||
void StatusPrint( int r, int g, int b, bool overwrite, const char *text );
|
||||
|
||||
virtual void redraw();
|
||||
virtual bool PaintBackground( void );
|
||||
|
||||
virtual int handleEvent( mxEvent *event );
|
||||
|
||||
// virtual void Think( float dt );
|
||||
|
||||
private:
|
||||
|
||||
void PositionSliders( int sboffset );
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_TEXT_LINES = 1024,
|
||||
TEXT_LINE_MASK = MAX_TEXT_LINES - 1,
|
||||
};
|
||||
|
||||
struct TextLine
|
||||
{
|
||||
char m_szText[ 512 ];
|
||||
int r, g, b;
|
||||
float curtime;
|
||||
};
|
||||
|
||||
TextLine m_rgTextLines[ MAX_TEXT_LINES ];
|
||||
int m_nCurrentLine;
|
||||
|
||||
mxScrollbar *m_pScrollbar;
|
||||
};
|
||||
|
||||
extern CStatusWindow *g_pStatusWindow;
|
||||
|
||||
#endif // STATUSWINDOW_H
|
||||
@@ -0,0 +1,484 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "tabwindow.h"
|
||||
#include "DrawHelper.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
// Input : *parent -
|
||||
// x -
|
||||
// y -
|
||||
// w -
|
||||
// h -
|
||||
// id -
|
||||
// style -
|
||||
//-----------------------------------------------------------------------------
|
||||
CTabWindow::CTabWindow( mxWindow *parent, int x, int y, int w, int h, int id /*= 0*/, int style /*=0*/ )
|
||||
: mxWindow( parent, x, y, w, h, "", style )
|
||||
{
|
||||
setId( id );
|
||||
|
||||
m_nSelected = -1;
|
||||
|
||||
m_nRowHeight = 20;
|
||||
m_nRowsRequired = 1;
|
||||
|
||||
m_nTabWidth = 80;
|
||||
m_nPixelDelta = 3;
|
||||
m_bInverted = false;
|
||||
m_bRightJustify = false;
|
||||
SetColor( COLOR_BG, GetSysColor( COLOR_BTNFACE ) );
|
||||
SetColor( COLOR_FG, GetSysColor( COLOR_INACTIVECAPTION ) );
|
||||
SetColor( COLOR_FG_SELECTED, GetSysColor( COLOR_ACTIVECAPTION ) );
|
||||
SetColor( COLOR_HILITE, GetSysColor( COLOR_3DSHADOW ) );
|
||||
SetColor( COLOR_HILITE_SELECTED, GetSysColor( COLOR_3DHILIGHT ) );
|
||||
SetColor( COLOR_TEXT, GetSysColor( COLOR_BTNTEXT ) );
|
||||
SetColor( COLOR_TEXT_SELECTED, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
|
||||
|
||||
SceneManager_AddWindowStyle( this, WS_CLIPCHILDREN | WS_CLIPSIBLINGS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : CTabWindow::~CTabWindow
|
||||
//-----------------------------------------------------------------------------
|
||||
CTabWindow::~CTabWindow ( void )
|
||||
{
|
||||
removeAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : index -
|
||||
// clr -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTabWindow::SetColor( int index, COLORREF clr )
|
||||
{
|
||||
if ( index < 0 || index >= NUM_COLORS )
|
||||
return;
|
||||
|
||||
m_Colors[ index ] = clr;
|
||||
}
|
||||
|
||||
void CTabWindow::SetInverted( bool invert )
|
||||
{
|
||||
m_bInverted = invert;
|
||||
RecomputeLayout( w2() );
|
||||
}
|
||||
|
||||
void CTabWindow::SetRightJustify( bool rightjustify )
|
||||
{
|
||||
m_bRightJustify = true;
|
||||
RecomputeLayout( w2() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Tabs are sized to string content
|
||||
// Input : rcClient -
|
||||
// tabRect -
|
||||
// tabNum -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTabWindow::GetTabRect( const RECT& rcClient, RECT& tabRect, int tabNum )
|
||||
{
|
||||
tabRect = m_Items[ tabNum ].rect;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : drawHelper -
|
||||
// rcClient -
|
||||
// tabnum -
|
||||
// selected -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTabWindow::DrawTab( CDrawHelper& drawHelper, RECT& rcClient, int tabnum, bool selected )
|
||||
{
|
||||
RECT rcTab;
|
||||
|
||||
if ( tabnum < 0 || tabnum >= m_Items.Size() )
|
||||
return;
|
||||
|
||||
#if defined( _DEBUG )
|
||||
CETItem *p = &m_Items[ tabnum ];
|
||||
Assert( p );
|
||||
#endif
|
||||
|
||||
GetTabRect( rcClient, rcTab, tabnum );
|
||||
|
||||
COLORREF fgcolor = m_Colors[ selected ? COLOR_FG_SELECTED : COLOR_FG ];
|
||||
COLORREF hilightcolor = m_Colors[ selected ? COLOR_HILITE_SELECTED : COLOR_HILITE ];
|
||||
COLORREF text = m_Colors[ selected ? COLOR_TEXT_SELECTED : COLOR_TEXT ];
|
||||
|
||||
// Create a trapezoid/paralleogram
|
||||
POINT region[4];
|
||||
int cPoints = 4;
|
||||
|
||||
OffsetRect( &rcTab, 0, m_bInverted ? 1 : -1 );
|
||||
|
||||
if ( m_bInverted )
|
||||
{
|
||||
region[ 0 ].x = rcTab.left - m_nPixelDelta;
|
||||
region[ 0 ].y = rcTab.top;
|
||||
|
||||
region[ 1 ].x = rcTab.right + m_nPixelDelta;
|
||||
region[ 1 ].y = rcTab.top;
|
||||
|
||||
region[ 2 ].x = rcTab.right - m_nPixelDelta;
|
||||
region[ 2 ].y = rcTab.bottom;
|
||||
|
||||
region[ 3 ].x = rcTab.left + m_nPixelDelta;
|
||||
region[ 3 ].y = rcTab.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
region[ 0 ].x = rcTab.left + m_nPixelDelta;
|
||||
region[ 0 ].y = rcTab.top;
|
||||
|
||||
region[ 1 ].x = rcTab.right - m_nPixelDelta;
|
||||
region[ 1 ].y = rcTab.top;
|
||||
|
||||
region[ 2 ].x = rcTab.right + m_nPixelDelta;
|
||||
region[ 2 ].y = rcTab.bottom;
|
||||
|
||||
region[ 3 ].x = rcTab.left - m_nPixelDelta;
|
||||
region[ 3 ].y = rcTab.bottom;
|
||||
}
|
||||
|
||||
HDC dc = drawHelper.GrabDC();
|
||||
|
||||
HRGN rgn = CreatePolygonRgn( region, cPoints, ALTERNATE );
|
||||
|
||||
int oldPF = SetPolyFillMode( dc, ALTERNATE );
|
||||
|
||||
HBRUSH brBg = CreateSolidBrush( fgcolor );
|
||||
HBRUSH brBorder = CreateSolidBrush( hilightcolor );
|
||||
//HBRUSH brInset = CreateSolidBrush( fgcolor );
|
||||
|
||||
FillRgn( dc, rgn, brBg );
|
||||
FrameRgn( dc, rgn, brBorder, 1, 1 );
|
||||
|
||||
SetPolyFillMode( dc, oldPF );
|
||||
|
||||
DeleteObject( rgn );
|
||||
|
||||
DeleteObject( brBg );
|
||||
DeleteObject( brBorder );
|
||||
//DeleteObject( brInset );
|
||||
|
||||
// Position label
|
||||
InflateRect( &rcTab, -5, 0 );
|
||||
OffsetRect( &rcTab, 2, 0 );
|
||||
|
||||
// Draw label
|
||||
drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, text, rcTab, "%s%s", getPrefix( tabnum ), getLabel( tabnum ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTabWindow::redraw( void )
|
||||
{
|
||||
CDrawHelper drawHelper( this, m_Colors[ COLOR_BG ] );
|
||||
|
||||
int liney = m_bInverted ? 1 : h2() - 2;
|
||||
|
||||
drawHelper.DrawColoredLine( m_Colors[ COLOR_HILITE ], PS_SOLID, 1, 0, liney, w(), liney );
|
||||
RECT rc;
|
||||
drawHelper.GetClientRect( rc );
|
||||
|
||||
// Draw non-selected first
|
||||
for ( int i = 0 ; i < m_Items.Size(); i++ )
|
||||
{
|
||||
if ( i == m_nSelected )
|
||||
continue;
|
||||
|
||||
DrawTab( drawHelper, rc, i );
|
||||
}
|
||||
|
||||
// Draw selected last, so that it appears to pop to top of z order
|
||||
if ( m_nSelected >= 0 && m_nSelected < m_Items.Size() )
|
||||
{
|
||||
DrawTab( drawHelper, rc, m_nSelected, true );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : mx -
|
||||
// my -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CTabWindow::GetItemUnderMouse( int mx, int my )
|
||||
{
|
||||
RECT rcClient;
|
||||
GetClientRect( (HWND)getHandle(), &rcClient );
|
||||
|
||||
for ( int i = 0; i < m_Items.Size() ; i++ )
|
||||
{
|
||||
RECT rcTab;
|
||||
GetTabRect( rcClient, rcTab, i );
|
||||
|
||||
if ( mx < rcTab.left ||
|
||||
mx > rcTab.right ||
|
||||
my < rcTab.top ||
|
||||
my > rcTab.bottom )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *event -
|
||||
// Output : int CTabWindow::handleEvent
|
||||
//-----------------------------------------------------------------------------
|
||||
int CTabWindow::handleEvent (mxEvent *event)
|
||||
{
|
||||
int iret = 0;
|
||||
|
||||
switch ( event->event )
|
||||
{
|
||||
case mxEvent::MouseDown:
|
||||
{
|
||||
int item = GetItemUnderMouse( (short)event->x, (short)event->y );
|
||||
if ( item != -1 )
|
||||
{
|
||||
m_nSelected = item;
|
||||
redraw();
|
||||
|
||||
// Send CBN_SELCHANGE WM_COMMAND message to parent
|
||||
HWND parent = (HWND)( getParent() ? getParent()->getHandle() : NULL );
|
||||
if ( parent )
|
||||
{
|
||||
LPARAM lp;
|
||||
WPARAM wp;
|
||||
|
||||
wp = MAKEWPARAM( getId(), CBN_SELCHANGE );
|
||||
lp = (long)getHandle();
|
||||
|
||||
PostMessage( parent, WM_COMMAND, wp, lp );
|
||||
}
|
||||
iret = 1;
|
||||
}
|
||||
|
||||
if ( event->buttons & mxEvent::MouseRightButton )
|
||||
{
|
||||
ShowRightClickMenu( (short)event->x, (short)event->y );
|
||||
iret = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case mxEvent::Size:
|
||||
{
|
||||
RecomputeLayout( w2() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
return iret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Add string to table
|
||||
// Input : *item -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTabWindow::add( const char *item )
|
||||
{
|
||||
m_Items.AddToTail();
|
||||
CETItem *p = &m_Items[ m_Items.Size() - 1 ];
|
||||
Assert( p );
|
||||
|
||||
Q_memset( &p->rect, 0, sizeof( p->rect) );
|
||||
|
||||
strcpy( p->m_szString, item );
|
||||
p->m_szPrefix[ 0 ] = 0;
|
||||
m_nSelected = min( m_nSelected, m_Items.Size() - 1 );
|
||||
m_nSelected = max( m_nSelected, 0 );
|
||||
|
||||
RecomputeLayout( w2() );
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
void CTabWindow::setPrefix( int item, char const *prefix )
|
||||
{
|
||||
if ( item < 0 || item >= m_Items.Size() )
|
||||
return;
|
||||
|
||||
strncpy( m_Items[ item ].m_szPrefix, prefix, sizeof( m_Items[ item ].m_szPrefix ) );
|
||||
// RecomputeLayout( w2() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Change selected item
|
||||
// Input : index -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTabWindow::select( int index )
|
||||
{
|
||||
if ( index < 0 || index >= m_Items.Size() )
|
||||
return;
|
||||
|
||||
m_nSelected = index;
|
||||
redraw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Remove a string
|
||||
// Input : index -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTabWindow::remove( int index )
|
||||
{
|
||||
if ( index < 0 || index >= m_Items.Size() )
|
||||
return;
|
||||
|
||||
m_Items.Remove( index );
|
||||
|
||||
m_nSelected = min( m_nSelected, m_Items.Size() - 1 );
|
||||
m_nSelected = max( m_nSelected, 0 );
|
||||
|
||||
RecomputeLayout( w2() );
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Clear out everything
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTabWindow::removeAll()
|
||||
{
|
||||
m_nSelected = -1;
|
||||
m_Items.RemoveAll();
|
||||
|
||||
RecomputeLayout( w2() );
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CTabWindow::getItemCount () const
|
||||
{
|
||||
return m_Items.Size();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CTabWindow::getSelectedIndex () const
|
||||
{
|
||||
// Convert based on override index
|
||||
return m_nSelected;
|
||||
}
|
||||
|
||||
char const *CTabWindow::getLabel( int item )
|
||||
{
|
||||
if ( item < 0 || item >= m_Items.Count() )
|
||||
return "";
|
||||
|
||||
return m_Items[ item ].m_szString;
|
||||
}
|
||||
|
||||
char const *CTabWindow::getPrefix( int item )
|
||||
{
|
||||
if ( item < 0 || item >= m_Items.Count() )
|
||||
return "";
|
||||
|
||||
return m_Items[ item ].m_szPrefix;
|
||||
}
|
||||
|
||||
void CTabWindow::SetRowHeight( int rowheight )
|
||||
{
|
||||
m_nRowHeight = rowheight;
|
||||
RecomputeLayout( w2() );
|
||||
redraw();
|
||||
}
|
||||
|
||||
int CTabWindow::GetBestHeight( int width )
|
||||
{
|
||||
return RecomputeLayout( width, false ) * m_nRowHeight;
|
||||
}
|
||||
|
||||
|
||||
int CTabWindow::RecomputeLayout( int windowWidth, bool dolayout /*=true*/ )
|
||||
{
|
||||
// Draw non-selected first
|
||||
int curedge = m_nPixelDelta + 1;
|
||||
int curtop = 0;
|
||||
|
||||
if ( m_bRightJustify )
|
||||
{
|
||||
curedge = windowWidth - ( m_nPixelDelta + 1 ) - 5;
|
||||
}
|
||||
|
||||
int startedge = curedge;
|
||||
|
||||
int currentrow = 0;
|
||||
|
||||
for ( int i = 0 ; i < m_Items.Size(); i++ )
|
||||
{
|
||||
CETItem *p = &m_Items[ i ];
|
||||
|
||||
RECT rc;
|
||||
|
||||
int textwidth = CDrawHelper::CalcTextWidth( "Arial", 9, FW_NORMAL, "%s%s", p->m_szPrefix, p->m_szString ) + 15;
|
||||
|
||||
if ( !m_bRightJustify )
|
||||
{
|
||||
// Starting column
|
||||
if ( curedge + textwidth > windowWidth )
|
||||
{
|
||||
curedge = startedge;
|
||||
curtop += m_nRowHeight;
|
||||
currentrow++;
|
||||
}
|
||||
|
||||
rc.left = curedge;
|
||||
rc.right = curedge + textwidth;
|
||||
rc.top = curtop + 2;
|
||||
rc.bottom = curtop + m_nRowHeight;
|
||||
|
||||
curedge += textwidth;
|
||||
|
||||
p->rect = rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Starting column
|
||||
if ( curedge - textwidth < 0 )
|
||||
{
|
||||
curedge = startedge;
|
||||
curtop += m_nRowHeight;
|
||||
currentrow++;
|
||||
}
|
||||
|
||||
rc.left = curedge - textwidth;
|
||||
rc.right = curedge;
|
||||
rc.top = curtop;
|
||||
rc.bottom = curtop + m_nRowHeight - 2;
|
||||
|
||||
curedge -= textwidth;
|
||||
}
|
||||
|
||||
if ( dolayout )
|
||||
{
|
||||
p->rect = rc;
|
||||
}
|
||||
}
|
||||
|
||||
if ( dolayout )
|
||||
{
|
||||
m_nRowsRequired = currentrow + 1;
|
||||
}
|
||||
|
||||
return currentrow + 1;
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TABWINDOW_H
|
||||
#define TABWINDOW_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <mxtk/mx.h>
|
||||
#include "utlvector.h"
|
||||
|
||||
class CDrawHelper;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A custom tab control for handling expression class strings
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTabWindow : public mxWindow
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
COLOR_BG = 0,
|
||||
COLOR_FG,
|
||||
COLOR_FG_SELECTED,
|
||||
COLOR_HILITE,
|
||||
COLOR_HILITE_SELECTED,
|
||||
COLOR_TEXT,
|
||||
COLOR_TEXT_SELECTED,
|
||||
|
||||
NUM_COLORS
|
||||
};
|
||||
|
||||
CTabWindow( mxWindow *parent, int x, int y, int w, int h, int id = 0, int style = 0 );
|
||||
virtual ~CTabWindow ( void );
|
||||
|
||||
virtual void redraw( void );
|
||||
virtual int handleEvent (mxEvent *event);
|
||||
|
||||
// MANIPULATORS
|
||||
virtual void add (const char *item);
|
||||
virtual void select (int index);
|
||||
virtual void remove (int index);
|
||||
virtual void removeAll ();
|
||||
virtual void setPrefix( int item, char const *prefix );
|
||||
|
||||
// ACCESSORS
|
||||
virtual int getItemCount () const;
|
||||
virtual int getSelectedIndex () const;
|
||||
|
||||
virtual char const *getLabel( int item );
|
||||
virtual char const *getPrefix( int item );
|
||||
|
||||
virtual void ShowRightClickMenu( int mx, int my ) = 0;
|
||||
|
||||
void SetColor( int index, COLORREF clr );
|
||||
|
||||
void SetInverted( bool invert );
|
||||
void SetRightJustify( bool rightjustify );
|
||||
|
||||
int GetBestHeight( int width );
|
||||
void SetRowHeight( int rowheight );
|
||||
|
||||
protected:
|
||||
void GetTabRect( const RECT& rcClient, RECT& tabRect, int tabNum );
|
||||
virtual void DrawTab( CDrawHelper& drawHelper, RECT& rcClient, int tabnum, bool selected = false );
|
||||
|
||||
int RecomputeLayout( int windowWidth, bool dolayout = true );
|
||||
|
||||
class CETItem
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_ET_STRING_LENGTH = 64
|
||||
};
|
||||
|
||||
char m_szString[ MAX_ET_STRING_LENGTH ];
|
||||
char m_szPrefix[ MAX_ET_STRING_LENGTH ];
|
||||
RECT rect;
|
||||
};
|
||||
|
||||
int GetItemUnderMouse( int mx, int my );
|
||||
|
||||
CUtlVector <CETItem> m_Items;
|
||||
int m_nRowsRequired;
|
||||
|
||||
int m_nSelected;
|
||||
|
||||
int m_nTabWidth;
|
||||
int m_nPixelDelta;
|
||||
bool m_bInverted;
|
||||
bool m_bRightJustify;
|
||||
|
||||
COLORREF m_Colors[ NUM_COLORS ];
|
||||
|
||||
int m_nRowHeight;
|
||||
};
|
||||
#endif // TABWINDOW_H
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,284 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "vcdfile.h"
|
||||
#include "soundentry.h"
|
||||
#include "choreoscene.h"
|
||||
#include "scriplib.h"
|
||||
#include "cmdlib.h"
|
||||
#include "iscenetokenprocessor.h"
|
||||
#include "choreoevent.h"
|
||||
#include "scene.h"
|
||||
#include "project.h"
|
||||
#include "workspacemanager.h"
|
||||
#include "workspacebrowser.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Helper to scene module for parsing the .vcd file
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSceneTokenProcessor : public ISceneTokenProcessor
|
||||
{
|
||||
public:
|
||||
const char *CurrentToken( void );
|
||||
bool GetToken( bool crossline );
|
||||
bool TokenAvailable( void );
|
||||
void Error( const char *fmt, ... );
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : const
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CSceneTokenProcessor::CurrentToken( void )
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : crossline -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSceneTokenProcessor::GetToken( bool crossline )
|
||||
{
|
||||
return ::GetToken( crossline ) ? true : false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSceneTokenProcessor::TokenAvailable( void )
|
||||
{
|
||||
return ::TokenAvailable() ? true : false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *fmt -
|
||||
// ... -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSceneTokenProcessor::Error( const char *fmt, ... )
|
||||
{
|
||||
char string[ 2048 ];
|
||||
va_list argptr;
|
||||
va_start( argptr, fmt );
|
||||
vsprintf( string, fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
Con_ColorPrintf( ERROR_R, ERROR_G, ERROR_B, string );
|
||||
::Error( string );
|
||||
}
|
||||
|
||||
static CSceneTokenProcessor g_TokenProcessor;
|
||||
ISceneTokenProcessor *tokenprocessor = &g_TokenProcessor;
|
||||
|
||||
CVCDFile::CVCDFile( CScene *scene, char const *filename ) : m_pOwner( scene )
|
||||
{
|
||||
Q_strncpy( m_szName, filename, sizeof( m_szName ) );
|
||||
|
||||
m_pScene = LoadScene( filename );
|
||||
LoadSoundsFromScene( m_pScene );
|
||||
|
||||
m_pszComments = NULL;
|
||||
}
|
||||
|
||||
CVCDFile::~CVCDFile()
|
||||
{
|
||||
while ( m_Sounds.Count() > 0 )
|
||||
{
|
||||
CSoundEntry *p = m_Sounds[ 0 ];
|
||||
m_Sounds.Remove( 0 );
|
||||
delete p;
|
||||
}
|
||||
delete[] m_pszComments;
|
||||
}
|
||||
|
||||
CScene *CVCDFile::GetOwnerScene()
|
||||
{
|
||||
return m_pOwner;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *filename -
|
||||
// Output : CChoreoScene
|
||||
//-----------------------------------------------------------------------------
|
||||
CChoreoScene *CVCDFile::LoadScene( char const *filename )
|
||||
{
|
||||
if ( filesystem->FileExists( filename ) )
|
||||
{
|
||||
char fullpath[ 512 ];
|
||||
filesystem->RelativePathToFullPath( filename, "GAME", fullpath, sizeof( fullpath ) );
|
||||
LoadScriptFile( fullpath );
|
||||
CChoreoScene *scene = ChoreoLoadScene( filename, this, &g_TokenProcessor, Con_Printf );
|
||||
return scene;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CVCDFile::LoadSoundsFromScene( CChoreoScene *scene )
|
||||
{
|
||||
if ( !scene )
|
||||
return;
|
||||
|
||||
CChoreoEvent *e;
|
||||
|
||||
int c = scene->GetNumEvents();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
e = scene->GetEvent( i );
|
||||
if ( !e )
|
||||
continue;
|
||||
|
||||
if ( e->GetType() != CChoreoEvent::SPEAK )
|
||||
continue;
|
||||
|
||||
CSoundEntry *se = new CSoundEntry( this, e->GetParameters() );
|
||||
m_Sounds.AddToTail( se );
|
||||
}
|
||||
}
|
||||
|
||||
char const *CVCDFile::GetName() const
|
||||
{
|
||||
return m_szName;
|
||||
}
|
||||
|
||||
char const *CVCDFile::GetComments()
|
||||
{
|
||||
return m_pszComments ? m_pszComments : "";
|
||||
}
|
||||
|
||||
void CVCDFile::SetComments( char const *comments )
|
||||
{
|
||||
delete[] m_pszComments;
|
||||
m_pszComments = V_strdup( comments );
|
||||
|
||||
if ( GetOwnerScene() )
|
||||
{
|
||||
if ( GetOwnerScene()->GetOwnerProject() )
|
||||
{
|
||||
GetOwnerScene()->GetOwnerProject()->SetDirty( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CVCDFile::GetSoundEntryCount() const
|
||||
{
|
||||
return m_Sounds.Count();
|
||||
}
|
||||
|
||||
CSoundEntry *CVCDFile::GetSoundEntry( int index )
|
||||
{
|
||||
if ( index < 0 || index >= m_Sounds.Count() )
|
||||
return NULL;
|
||||
return m_Sounds[ index ];
|
||||
}
|
||||
|
||||
void CVCDFile::ValidateTree( mxTreeView *tree, mxTreeViewItem* parent )
|
||||
{
|
||||
CUtlVector< mxTreeViewItem * > m_KnownItems;
|
||||
|
||||
int c = GetSoundEntryCount();
|
||||
CSoundEntry *sound;
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
sound = GetSoundEntry( i );
|
||||
if ( !sound )
|
||||
continue;
|
||||
|
||||
char sz[ 256 ];
|
||||
Q_snprintf( sz, sizeof( sz ), "\"%s\" : script %s", sound->GetName(), sound->GetScriptFile() );
|
||||
|
||||
mxTreeViewItem *spot = sound->FindItem( tree, parent );
|
||||
if ( !spot )
|
||||
{
|
||||
spot = tree->add( parent, sz );
|
||||
}
|
||||
|
||||
m_KnownItems.AddToTail( spot );
|
||||
|
||||
sound->SetOrdinal( i );
|
||||
|
||||
tree->setLabel( spot, sz );
|
||||
|
||||
tree->setImages( spot, sound->GetIconIndex(), sound->GetIconIndex() );
|
||||
tree->setUserData( spot, sound );
|
||||
|
||||
sound->ValidateTree( tree, spot );
|
||||
}
|
||||
|
||||
mxTreeViewItem *start = tree->getFirstChild( parent );
|
||||
while ( start )
|
||||
{
|
||||
mxTreeViewItem *next = tree->getNextChild( start );
|
||||
|
||||
if ( m_KnownItems.Find( start ) == m_KnownItems.InvalidIndex() )
|
||||
{
|
||||
tree->remove( start );
|
||||
}
|
||||
|
||||
start = next;
|
||||
}
|
||||
|
||||
tree->sortTree( parent, true, CWorkspaceBrowser::CompareFunc, 0 );
|
||||
}
|
||||
|
||||
void CVCDFile::Checkout(bool updatestateicons /*= true*/)
|
||||
{
|
||||
VSS_Checkout( GetName(), updatestateicons );
|
||||
}
|
||||
|
||||
void CVCDFile::Checkin(bool updatestateicons /*= true*/)
|
||||
{
|
||||
VSS_Checkin( GetName(), updatestateicons );
|
||||
}
|
||||
|
||||
|
||||
bool CVCDFile::IsCheckedOut() const
|
||||
{
|
||||
return filesystem->IsFileWritable( GetName() );
|
||||
}
|
||||
|
||||
int CVCDFile::GetIconIndex() const
|
||||
{
|
||||
if ( IsCheckedOut() )
|
||||
{
|
||||
return IMAGE_VCD_CHECKEDOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IMAGE_VCD;
|
||||
}
|
||||
}
|
||||
|
||||
void CVCDFile::MoveChildUp( ITreeItem *child )
|
||||
{
|
||||
}
|
||||
|
||||
void CVCDFile::MoveChildDown( ITreeItem *child )
|
||||
{
|
||||
}
|
||||
|
||||
void CVCDFile::SetDirty( bool dirty )
|
||||
{
|
||||
if ( GetOwnerScene() )
|
||||
{
|
||||
GetOwnerScene()->SetDirty( dirty );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CVCDFile::IsChildFirst( ITreeItem *child )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CVCDFile::IsChildLast( ITreeItem *child )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VCDFILE_H
|
||||
#define VCDFILE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CSoundEntry;
|
||||
class CScene;
|
||||
|
||||
#include "itreeitem.h"
|
||||
#include "ichoreoeventcallback.h"
|
||||
|
||||
class CChoreoScene;
|
||||
|
||||
class CVCDFile : public ITreeItem, public IChoreoEventCallback
|
||||
{
|
||||
public:
|
||||
CVCDFile( CScene *scene, char const *filename );
|
||||
~CVCDFile();
|
||||
|
||||
CScene *GetOwnerScene();
|
||||
|
||||
char const *GetName() const;
|
||||
char const *GetComments();
|
||||
void SetComments( char const *comments );
|
||||
|
||||
int GetSoundEntryCount() const;
|
||||
CSoundEntry *GetSoundEntry( int index );
|
||||
|
||||
void ValidateTree( mxTreeView *tree, mxTreeViewItem* parent );
|
||||
|
||||
// ITreeItem
|
||||
virtual CWorkspace *GetWorkspace() { return NULL; }
|
||||
virtual CProject *GetProject() { return NULL; }
|
||||
virtual CScene *GetScene() { return NULL; }
|
||||
virtual CVCDFile *GetVCDFile() { return this; }
|
||||
virtual CSoundEntry *GetSoundEntry() { return NULL; }
|
||||
virtual CWaveFile *GetWaveFile() { return NULL; }
|
||||
|
||||
// IChoreoEventCallback stubs
|
||||
virtual void StartEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) {}
|
||||
// Only called for events with HasEndTime() == true
|
||||
virtual void EndEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) {}
|
||||
// Called for events which have been started but aren't done yet
|
||||
virtual void ProcessEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) {}
|
||||
// Called for events that are part of a pause condition
|
||||
virtual bool CheckEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) { return false; }
|
||||
|
||||
virtual void Checkout( bool updatestateicons = true );
|
||||
virtual void Checkin( bool updatestateicons = true );
|
||||
|
||||
bool IsCheckedOut() const;
|
||||
int GetIconIndex() const;
|
||||
|
||||
virtual void MoveChildUp( ITreeItem *child );
|
||||
virtual void MoveChildDown( ITreeItem *child );
|
||||
|
||||
void SetDirty( bool dirty );
|
||||
|
||||
virtual bool IsChildFirst( ITreeItem *child );
|
||||
virtual bool IsChildLast( ITreeItem *child );
|
||||
|
||||
private:
|
||||
|
||||
CChoreoScene *LoadScene( char const *filename );
|
||||
|
||||
void LoadSoundsFromScene( CChoreoScene *scene );
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_VCD_NAME = 128,
|
||||
};
|
||||
|
||||
char m_szName[ MAX_VCD_NAME ];
|
||||
char *m_pszComments;
|
||||
|
||||
CUtlVector< CSoundEntry * > m_Sounds;
|
||||
|
||||
CChoreoScene *m_pScene;
|
||||
|
||||
CScene *m_pOwner;
|
||||
};
|
||||
|
||||
#endif // VCDFILE_H
|
||||
@@ -0,0 +1,83 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include <mxtk/mx.h>
|
||||
#include <stdio.h>
|
||||
#include "resource.h"
|
||||
#include "VSSProperties.h"
|
||||
#include "workspacemanager.h"
|
||||
|
||||
static CVSSParams g_Params;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : hwndDlg -
|
||||
// uMsg -
|
||||
// wParam -
|
||||
// lParam -
|
||||
// Output : static BOOL CALLBACK
|
||||
//-----------------------------------------------------------------------------
|
||||
static BOOL CALLBACK VSSPropertiesDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
// Insert code here to put the string (to find and replace with)
|
||||
// into the edit controls.
|
||||
// ...
|
||||
{
|
||||
g_Params.PositionSelf( hwndDlg );
|
||||
|
||||
SetDlgItemText( hwndDlg, IDC_VSS_USERNAME, g_Params.m_szUserName );
|
||||
SetDlgItemText( hwndDlg, IDC_VSS_PROJECT, g_Params.m_szProject );
|
||||
|
||||
SetWindowText( hwndDlg, g_Params.m_szDialogTitle );
|
||||
|
||||
SetFocus( GetDlgItem( hwndDlg, IDC_VSS_USERNAME ) );
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_VSS_USERNAME ), EM_SETSEL, 0, MAKELONG(0, 0xffff) );
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
g_Params.m_szUserName[ 0 ] = 0;
|
||||
g_Params.m_szProject[ 0 ] = 0;
|
||||
GetDlgItemText( hwndDlg, IDC_VSS_USERNAME, g_Params.m_szUserName, sizeof( g_Params.m_szUserName ) );
|
||||
GetDlgItemText( hwndDlg, IDC_VSS_PROJECT, g_Params.m_szProject, sizeof( g_Params.m_szProject ) );
|
||||
EndDialog( hwndDlg, 1 );
|
||||
break;
|
||||
case IDCANCEL:
|
||||
EndDialog( hwndDlg, 0 );
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *view -
|
||||
// *actor -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int VSSProperties( CVSSParams *params )
|
||||
{
|
||||
g_Params = *params;
|
||||
|
||||
int retval = DialogBox( (HINSTANCE)GetModuleHandle( 0 ),
|
||||
MAKEINTRESOURCE( IDD_VSSPROPERTIES ),
|
||||
(HWND)GetWorkspaceManager()->getHandle(),
|
||||
(DLGPROC)VSSPropertiesDialogProc );
|
||||
|
||||
*params = g_Params;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VSSPROPERTIES_H
|
||||
#define VSSPROPERTIES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basedialogparams.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CVSSParams : public CBaseDialogParams
|
||||
{
|
||||
// Event descriptive name
|
||||
char m_szUserName[ 256 ];
|
||||
char m_szProject[ 256 ];
|
||||
};
|
||||
|
||||
int VSSProperties( CVSSParams *params );
|
||||
|
||||
#endif // VSSPROPERTIES_H
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,102 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef WAVEBROWSER_H
|
||||
#define WAVEBROWSER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "mxtk/mxListView.h"
|
||||
#include "commctrl.h"
|
||||
#include "utldict.h"
|
||||
|
||||
class CWorkspace;
|
||||
class CProject;
|
||||
class CScene;
|
||||
class CVCDFile;
|
||||
class CWaveFile;
|
||||
|
||||
class CWaveList;
|
||||
class CWorkspaceManager;
|
||||
class CWaveFilterTab;
|
||||
class CWaveOptionsWindow;
|
||||
class CWaveFileTree;
|
||||
|
||||
class CWaveBrowser : public mxWindow
|
||||
{
|
||||
typedef mxWindow BaseClass;
|
||||
public:
|
||||
|
||||
CWaveBrowser( mxWindow *parent, CWorkspaceManager *manager, int id );
|
||||
|
||||
virtual int handleEvent( mxEvent *event );
|
||||
virtual void OnDelete();
|
||||
|
||||
CWorkspaceManager *GetManager();
|
||||
|
||||
void RepopulateTree();
|
||||
|
||||
void BuildSelectionList( CUtlVector< CWaveFile * >& selected );
|
||||
|
||||
void OnPlay();
|
||||
|
||||
void JumpToItem( CWaveFile *wav );
|
||||
|
||||
CWaveFile *FindEntry( char const *wavname, bool jump = false );
|
||||
|
||||
|
||||
int GetSoundCount() const;
|
||||
CWaveFile *GetSound( int index );
|
||||
|
||||
void OnSearch();
|
||||
|
||||
private:
|
||||
|
||||
char const *GetSearchString();
|
||||
|
||||
bool LoadWaveFilesInDirectory( CUtlDict< CWaveFile *, int >& soundlist, char const* pDirectoryName, int nDirectoryNameLen );
|
||||
bool InitDirectoryRecursive( CUtlDict< CWaveFile *, int >& soundlist, char const* pDirectoryName );
|
||||
|
||||
void OnWaveProperties();
|
||||
void OnEnableVoiceDucking();
|
||||
void OnDisableVoiceDucking();
|
||||
void OnCheckout();
|
||||
void OnCheckin();
|
||||
|
||||
void OnImportSentence();
|
||||
void OnExportSentence();
|
||||
|
||||
void OnGetSentence();
|
||||
|
||||
void PopulateTree( char const *subdirectory, bool textsearch = false );
|
||||
|
||||
void ShowContextMenu( void );
|
||||
|
||||
void LoadAllSounds();
|
||||
void RemoveAllSounds();
|
||||
|
||||
CWaveList *m_pListView;
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_BITMAPS = 6,
|
||||
};
|
||||
|
||||
CWorkspaceManager *m_pManager;
|
||||
|
||||
CUtlDict< CWaveFile *, int > m_AllSounds;
|
||||
CUtlSymbolTable m_ScriptTable;
|
||||
|
||||
CUtlVector< CUtlSymbol > m_Scripts;
|
||||
|
||||
CWaveOptionsWindow *m_pOptions;
|
||||
CWaveFileTree *m_pFileTree;
|
||||
|
||||
CUtlVector< CWaveFile * > m_CurrentSelection;
|
||||
};
|
||||
|
||||
#endif // WAVEBROWSER_H
|
||||
@@ -0,0 +1,379 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "wavefile.h"
|
||||
#include "sentence.h"
|
||||
#include "iscenemanagersound.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "snd_wave_source.h"
|
||||
#include "cmdlib.h"
|
||||
#include "workspacemanager.h"
|
||||
#include "vcdfile.h"
|
||||
#include "workspacebrowser.h"
|
||||
#include "multiplerequest.h"
|
||||
#include "UtlBuffer.h"
|
||||
#include "scenemanager_tools.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *name -
|
||||
//-----------------------------------------------------------------------------
|
||||
CWaveFile::CWaveFile( CVCDFile *vcd, CSoundEntry *se, char const *filename )
|
||||
: m_pOwner( vcd ), m_pOwnerSE( se )
|
||||
{
|
||||
m_bSentenceLoaded = false;
|
||||
|
||||
m_Sentence.Reset();
|
||||
|
||||
Q_strncpy( m_szName, filename, sizeof( m_szName ) );
|
||||
|
||||
m_pWaveFile = NULL;
|
||||
|
||||
Q_snprintf( m_szFileName, sizeof( m_szFileName ), "sound/%s", filename );
|
||||
}
|
||||
|
||||
CWaveFile::~CWaveFile()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CWaveFile::GetLanguageId()
|
||||
{
|
||||
return GetWorkspaceManager()->GetLanguageId();
|
||||
}
|
||||
|
||||
void CWaveFile::EnsureSentence()
|
||||
{
|
||||
if ( m_bSentenceLoaded )
|
||||
return;
|
||||
|
||||
m_bSentenceLoaded = true;
|
||||
|
||||
if ( m_szFileName[ 0 ] )
|
||||
{
|
||||
SceneManager_LoadSentenceFromWavFile( m_szFileName, m_Sentence );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CWaveFile::HasLoadedSentenceInfo() const
|
||||
{
|
||||
return m_bSentenceLoaded;
|
||||
}
|
||||
|
||||
|
||||
CVCDFile *CWaveFile::GetOwnerVCDFile()
|
||||
{
|
||||
return m_pOwner;
|
||||
}
|
||||
|
||||
CSoundEntry *CWaveFile::GetOwnerSoundEntry()
|
||||
{
|
||||
return m_pOwnerSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *name -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWaveFile::SetName( char const *filename )
|
||||
{
|
||||
if ( !Q_stricmp( m_szName, filename ) )
|
||||
return;
|
||||
|
||||
Q_strncpy( m_szName, filename, sizeof( m_szName ) );
|
||||
|
||||
Q_snprintf( m_szFileName, sizeof( m_szFileName ), "sound/%s", filename );
|
||||
|
||||
if ( m_szFileName[ 0 ] )
|
||||
{
|
||||
SceneManager_LoadSentenceFromWavFile( m_szFileName, m_Sentence );
|
||||
m_bSentenceLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
char const *CWaveFile::GetName() const
|
||||
{
|
||||
return m_szName;
|
||||
}
|
||||
|
||||
char const *CWaveFile::GetFileName() const
|
||||
{
|
||||
return m_szFileName;
|
||||
}
|
||||
|
||||
char const *CWaveFile::GetSentenceText()
|
||||
{
|
||||
EnsureSentence();
|
||||
return m_Sentence.GetText();
|
||||
}
|
||||
|
||||
void CWaveFile::SetSentenceText( char const *newText )
|
||||
{
|
||||
EnsureSentence();
|
||||
if ( !Q_stricmp( GetSentenceText(), newText ) )
|
||||
return;
|
||||
|
||||
if ( !IsCheckedOut() )
|
||||
{
|
||||
int retval = MultipleRequest( va( "Check out '%s'?", GetFileName() ) );
|
||||
if ( retval != 0 )
|
||||
return;
|
||||
|
||||
VSS_Checkout( GetFileName() );
|
||||
}
|
||||
|
||||
m_Sentence.SetText( newText );
|
||||
|
||||
SceneManager_SaveSentenceToWavFile( GetFileName(), m_Sentence );
|
||||
}
|
||||
|
||||
void CWaveFile::ValidateTree( mxTreeView *tree, mxTreeViewItem* parent )
|
||||
{
|
||||
}
|
||||
|
||||
void CWaveFile::Play()
|
||||
{
|
||||
if ( !m_pWaveFile )
|
||||
{
|
||||
m_pWaveFile = sound->FindOrAddSound( m_szFileName );
|
||||
}
|
||||
|
||||
if ( !m_pWaveFile )
|
||||
{
|
||||
Con_Printf( "Can't play '%s', no wave file loaded\n", GetFileName() );
|
||||
return;
|
||||
}
|
||||
|
||||
Con_Printf( "Playing '%s' : '%s'\n", GetFileName(), GetSentenceText() );
|
||||
|
||||
CAudioMixer *temp;
|
||||
sound->PlaySound( m_pWaveFile, &temp );
|
||||
}
|
||||
|
||||
bool CWaveFile::GetVoiceDuck()
|
||||
{
|
||||
EnsureSentence();
|
||||
return m_Sentence.GetVoiceDuck();
|
||||
}
|
||||
|
||||
void CWaveFile::SetVoiceDuck( bool duck )
|
||||
{
|
||||
EnsureSentence();
|
||||
if ( GetVoiceDuck() == duck )
|
||||
return;
|
||||
|
||||
m_Sentence.SetVoiceDuck( duck );
|
||||
|
||||
if ( !IsCheckedOut() )
|
||||
{
|
||||
int retval = MultipleRequest( va( "Check out '%s'?", GetFileName() ) );
|
||||
if ( retval != 0 )
|
||||
return;
|
||||
|
||||
VSS_Checkout( GetFileName() );
|
||||
}
|
||||
|
||||
SceneManager_SaveSentenceToWavFile( GetFileName(), m_Sentence );
|
||||
}
|
||||
|
||||
void CWaveFile::ToggleVoiceDucking()
|
||||
{
|
||||
EnsureSentence();
|
||||
m_Sentence.SetVoiceDuck( !m_Sentence.GetVoiceDuck() );
|
||||
|
||||
if ( !IsCheckedOut() )
|
||||
{
|
||||
int retval = MultipleRequest( va( "Check out '%s'?", GetFileName() ) );
|
||||
if ( retval != 0 )
|
||||
return;
|
||||
|
||||
VSS_Checkout( GetFileName() );
|
||||
}
|
||||
|
||||
SceneManager_SaveSentenceToWavFile( GetFileName(), m_Sentence );
|
||||
}
|
||||
|
||||
bool CWaveFile::IsCheckedOut() const
|
||||
{
|
||||
return filesystem->IsFileWritable( GetFileName() );
|
||||
}
|
||||
|
||||
int CWaveFile::GetIconIndex() const
|
||||
{
|
||||
if ( IsCheckedOut() )
|
||||
{
|
||||
return IMAGE_WAV_CHECKEDOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IMAGE_WAV;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CWaveFile::Checkout(bool updatestateicons /*= true*/)
|
||||
{
|
||||
VSS_Checkout( GetFileName(), updatestateicons );
|
||||
}
|
||||
|
||||
void CWaveFile::Checkin(bool updatestateicons /*= true*/)
|
||||
{
|
||||
VSS_Checkin( GetFileName(), updatestateicons );
|
||||
}
|
||||
|
||||
|
||||
void CWaveFile::MoveChildUp( ITreeItem *child )
|
||||
{
|
||||
}
|
||||
|
||||
void CWaveFile::MoveChildDown( ITreeItem *child )
|
||||
{
|
||||
}
|
||||
|
||||
void CWaveFile::SetDirty( bool dirty )
|
||||
{
|
||||
if ( GetOwnerVCDFile() )
|
||||
{
|
||||
GetOwnerVCDFile()->SetDirty( dirty );
|
||||
}
|
||||
}
|
||||
|
||||
bool CWaveFile::IsChildFirst( ITreeItem *child )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CWaveFile::IsChildLast( ITreeItem *child )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : sentence -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWaveFile::SetThreadLoadedSentence( CSentence& sentence )
|
||||
{
|
||||
if ( m_bSentenceLoaded )
|
||||
return;
|
||||
|
||||
m_bSentenceLoaded = true;
|
||||
m_Sentence = sentence;
|
||||
}
|
||||
|
||||
#define WORD_DATA_EXTENSION ".txt"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *tempfile -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWaveFile::ExportValveDataChunk( char const *tempfile )
|
||||
{
|
||||
EnsureSentence();
|
||||
|
||||
if ( m_Sentence.m_Words.Count() <= 0 )
|
||||
{
|
||||
Con_ColorPrintf( ERROR_R, ERROR_G, ERROR_B, "CWaveFile::ExportValveDataChunk: Sentence has no word data\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
SafeCreatePath( va( "%s%s", SceneManager_GetGameDirectory(), (char *)tempfile ) );
|
||||
|
||||
FileHandle_t fh = filesystem->Open( tempfile, "wb" );
|
||||
if ( !fh )
|
||||
{
|
||||
Con_ColorPrintf( ERROR_R, ERROR_G, ERROR_B, "CWaveFile::ExportValveDataChunk: Unable to write to %s (read-only?)\n", tempfile );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Buffer and dump data
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
|
||||
m_Sentence.SaveToBuffer( buf );
|
||||
|
||||
filesystem->Write( buf.Base(), buf.TellPut(), fh );
|
||||
filesystem->Close(fh);
|
||||
|
||||
Con_Printf( "Exported %i words to %s\n", m_Sentence.m_Words.Count(), tempfile );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *tempfile -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWaveFile::ImportValveDataChunk( char const *tempfile )
|
||||
{
|
||||
EnsureSentence();
|
||||
|
||||
FileHandle_t fh = filesystem->Open( tempfile, "rb" );
|
||||
if ( !fh )
|
||||
{
|
||||
Con_ColorPrintf( ERROR_R, ERROR_G, ERROR_B, "CWaveFile::ImportValveDataChunk: Unable to read from %s\n", tempfile );
|
||||
return;
|
||||
}
|
||||
|
||||
int len = filesystem->Size( fh );
|
||||
if ( len <= 4 )
|
||||
{
|
||||
Con_ColorPrintf( ERROR_R, ERROR_G, ERROR_B, "CWaveFile::ImportValveDataChunk: File %s has length 0\n", tempfile );
|
||||
return;
|
||||
}
|
||||
|
||||
CSentence newSentence;
|
||||
|
||||
unsigned char *buf = new unsigned char[ len + 1 ];
|
||||
|
||||
filesystem->Read( buf, len, fh );
|
||||
filesystem->Close( fh );
|
||||
|
||||
newSentence.InitFromDataChunk( (void *)( buf ), len );
|
||||
|
||||
delete[] buf;
|
||||
|
||||
// See if we can write it out...
|
||||
if ( !IsCheckedOut() )
|
||||
{
|
||||
int retval = MultipleRequest( va( "Check out '%s'?", GetFileName() ) );
|
||||
if ( retval != 0 )
|
||||
return;
|
||||
|
||||
VSS_Checkout( GetFileName() );
|
||||
}
|
||||
|
||||
if ( !IsCheckedOut() )
|
||||
{
|
||||
MakeFileWriteable( GetFileName() );
|
||||
Con_Printf( "Unable to check out %s, forcing it to be writable instead!\n", GetFileName() );
|
||||
}
|
||||
|
||||
Con_Printf( "Imported %i words from %s\n", newSentence.m_Words.Count(), tempfile );
|
||||
|
||||
m_Sentence = newSentence;
|
||||
|
||||
SceneManager_SaveSentenceToWavFile( GetFileName(), m_Sentence );
|
||||
}
|
||||
|
||||
void CWaveFile::GetPhonemeExportFile( char *path, int maxlen )
|
||||
{
|
||||
char relative[ 512 ];
|
||||
strcpy( relative, GetFileName() );
|
||||
Q_StripExtension( relative, relative, sizeof( relative ) );
|
||||
Q_DefaultExtension( relative, WORD_DATA_EXTENSION, sizeof( relative ) );
|
||||
|
||||
Q_snprintf( path, maxlen, "phonemes/%s", relative );
|
||||
Q_FixSlashes( path );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef WAVEFILE_H
|
||||
#define WAVEFILE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "itreeitem.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "sentence.h"
|
||||
|
||||
class CSoundEntry;
|
||||
class CAudioSource;
|
||||
class CVCDFile;
|
||||
|
||||
class CWaveFile : public ITreeItem
|
||||
{
|
||||
public:
|
||||
// One or both may be valid
|
||||
CWaveFile( CVCDFile *vcd, CSoundEntry *se, char const *filename );
|
||||
|
||||
~CWaveFile();
|
||||
|
||||
static int GetLanguageId();
|
||||
|
||||
CVCDFile *GetOwnerVCDFile();
|
||||
CSoundEntry *GetOwnerSoundEntry();
|
||||
|
||||
void SetName( char const *filename );
|
||||
|
||||
char const *GetName() const;
|
||||
char const *GetFileName() const;
|
||||
|
||||
char const *GetSentenceText();
|
||||
void SetSentenceText( char const *newText );
|
||||
|
||||
void ValidateTree( mxTreeView *tree, mxTreeViewItem* parent );
|
||||
|
||||
bool HasLoadedSentenceInfo() const;
|
||||
void EnsureSentence();
|
||||
|
||||
|
||||
virtual CWorkspace *GetWorkspace() { return NULL; }
|
||||
virtual CProject *GetProject() { return NULL; }
|
||||
virtual CScene *GetScene() { return NULL; }
|
||||
virtual CVCDFile *GetVCDFile() { return NULL; }
|
||||
virtual CSoundEntry *GetSoundEntry() { return NULL; }
|
||||
virtual CWaveFile *GetWaveFile() { return this; }
|
||||
|
||||
void Play();
|
||||
|
||||
bool GetVoiceDuck();
|
||||
void SetVoiceDuck( bool duck );
|
||||
void ToggleVoiceDucking();
|
||||
|
||||
virtual void Checkout( bool updatestateicons = true );
|
||||
virtual void Checkin( bool updatestateicons = true );
|
||||
|
||||
bool IsCheckedOut() const;
|
||||
int GetIconIndex() const;
|
||||
|
||||
virtual void MoveChildUp( ITreeItem *child );
|
||||
virtual void MoveChildDown( ITreeItem *child );
|
||||
|
||||
virtual void SetDirty( bool dirty );
|
||||
|
||||
virtual bool IsChildFirst( ITreeItem *child );
|
||||
virtual bool IsChildLast( ITreeItem *child );
|
||||
|
||||
void SetThreadLoadedSentence( CSentence& sentence );
|
||||
|
||||
void ExportValveDataChunk( char const *tempfile );
|
||||
void ImportValveDataChunk( char const *tempfile );
|
||||
|
||||
void GetPhonemeExportFile( char *path, int maxlen );
|
||||
|
||||
private:
|
||||
|
||||
CAudioSource *m_pWaveFile;
|
||||
CSentence m_Sentence;
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_SOUND_NAME = 256,
|
||||
MAX_SCRIPT_FILE = 64,
|
||||
MAX_SOUND_FILENAME = 128,
|
||||
};
|
||||
|
||||
char m_szName[ MAX_SOUND_FILENAME ];
|
||||
char m_szFileName[ MAX_SOUND_FILENAME ];
|
||||
|
||||
CVCDFile *m_pOwner;
|
||||
CSoundEntry *m_pOwnerSE;
|
||||
|
||||
bool m_bSentenceLoaded;
|
||||
};
|
||||
|
||||
#endif // WAVEFILE_H
|
||||
@@ -0,0 +1,193 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include <mxtk/mx.h>
|
||||
#include <stdio.h>
|
||||
#include "resource.h"
|
||||
#include "WaveProperties.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "soundentry.h"
|
||||
#include "cmdlib.h"
|
||||
#include "workspacemanager.h"
|
||||
#include "wavebrowser.h"
|
||||
#include "wavefile.h"
|
||||
#include "multiplerequest.h"
|
||||
|
||||
static CWaveParams g_Params;
|
||||
|
||||
static bool WaveLessFunc( const char *const& name1, const char *const& name2 )
|
||||
{
|
||||
if ( stricmp( name1, name2 ) < 0 )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void WaveProperties_OnOK( HWND hwndDlg )
|
||||
{
|
||||
// Gather info and make changes
|
||||
CWaveFile *item = g_Params.items[ 0 ];
|
||||
char sentencetext[ 512 ];
|
||||
|
||||
GetDlgItemText( hwndDlg, IDC_SENTENCETEXT, sentencetext, sizeof( sentencetext ) );
|
||||
|
||||
bool voiceduck = SendMessage( GetDlgItem( hwndDlg, IDC_VOICEDUCK ), BM_GETCHECK, 0, 0 ) == BST_CHECKED ? true : false;
|
||||
|
||||
MultipleRequestChangeContext();
|
||||
|
||||
// Update ducking on wav files
|
||||
item->SetVoiceDuck( voiceduck );
|
||||
item->SetSentenceText( sentencetext );
|
||||
|
||||
// Repopulate things
|
||||
GetWorkspaceManager()->RefreshBrowsers();
|
||||
}
|
||||
|
||||
char *Q_stristr_slash( char const *pStr, char const *pSearch );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : hwndDlg -
|
||||
//-----------------------------------------------------------------------------
|
||||
static void WaveProperties_ExportSentence()
|
||||
{
|
||||
int c = g_Params.items.Count();
|
||||
if ( c <= 0 )
|
||||
return;
|
||||
|
||||
MultipleRequestChangeContext();
|
||||
|
||||
int i;
|
||||
for ( i = 0; i < c; i++ )
|
||||
{
|
||||
CWaveFile *item = g_Params.items[ i ];
|
||||
Assert( item );
|
||||
|
||||
char relative[ 512 ];
|
||||
item->GetPhonemeExportFile( relative, sizeof( relative ) );
|
||||
if ( filesystem->FileExists( relative ) )
|
||||
{
|
||||
int retval = MultipleRequest( va( "Overwrite '%s'?", relative ) );
|
||||
if ( retval != 0 )
|
||||
continue;
|
||||
|
||||
filesystem->RemoveFile( relative );
|
||||
}
|
||||
|
||||
item->ExportValveDataChunk( relative );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : hwndDlg -
|
||||
//-----------------------------------------------------------------------------
|
||||
static void WaveProperties_ImportSentence()
|
||||
{
|
||||
int c = g_Params.items.Count();
|
||||
if ( c <= 0 )
|
||||
return;
|
||||
|
||||
int i;
|
||||
for ( i = 0; i < c; i++ )
|
||||
{
|
||||
CWaveFile *item = g_Params.items[ i ];
|
||||
Assert( item );
|
||||
|
||||
char relative[ 512 ];
|
||||
item->GetPhonemeExportFile( relative, sizeof( relative ) );
|
||||
if ( filesystem->FileExists( relative ) )
|
||||
{
|
||||
item->ImportValveDataChunk( relative );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : hwndDlg -
|
||||
// Output : static
|
||||
//-----------------------------------------------------------------------------
|
||||
static void WaveProperties_InitSentenceData( HWND hwndDlg )
|
||||
{
|
||||
CWaveFile *item = g_Params.items[ 0 ];
|
||||
|
||||
SetDlgItemText( hwndDlg, IDC_WAVENAME, item->GetName() );
|
||||
SetDlgItemText( hwndDlg, IDC_SENTENCETEXT, item->GetSentenceText() );
|
||||
|
||||
SendMessage( GetDlgItem( hwndDlg, IDC_VOICEDUCK ), BM_SETCHECK,
|
||||
( WPARAM ) item->GetVoiceDuck() ? BST_CHECKED : BST_UNCHECKED,
|
||||
( LPARAM )0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : hwndDlg -
|
||||
// uMsg -
|
||||
// wParam -
|
||||
// lParam -
|
||||
// Output : static BOOL CALLBACK
|
||||
//-----------------------------------------------------------------------------
|
||||
static BOOL CALLBACK WavePropertiesDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
g_Params.PositionSelf( hwndDlg );
|
||||
|
||||
WaveProperties_InitSentenceData( hwndDlg );
|
||||
|
||||
SetWindowText( hwndDlg, g_Params.m_szDialogTitle );
|
||||
|
||||
SetFocus( GetDlgItem( hwndDlg, IDC_WAVENAME ) );
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
{
|
||||
WaveProperties_OnOK( hwndDlg );
|
||||
|
||||
EndDialog( hwndDlg, 1 );
|
||||
}
|
||||
break;
|
||||
case IDCANCEL:
|
||||
EndDialog( hwndDlg, 0 );
|
||||
break;
|
||||
case IDC_EXPORTSENTENCE:
|
||||
WaveProperties_ExportSentence();
|
||||
break;
|
||||
case IDC_IMPORTSENTENCE:
|
||||
WaveProperties_ImportSentence();
|
||||
WaveProperties_InitSentenceData( hwndDlg );
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *view -
|
||||
// *actor -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int WaveProperties( CWaveParams *params )
|
||||
{
|
||||
g_Params = *params;
|
||||
|
||||
int retval = DialogBox( (HINSTANCE)GetModuleHandle( 0 ),
|
||||
MAKEINTRESOURCE( IDD_WAVEPROPERTIES ),
|
||||
(HWND)GetWorkspaceManager()->getHandle(),
|
||||
(DLGPROC)WavePropertiesDialogProc );
|
||||
|
||||
*params = g_Params;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef WAVEPROPERTIES_H
|
||||
#define WAVEPROPERTIES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basedialogparams.h"
|
||||
|
||||
class CWaveFile;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CWaveParams : public CBaseDialogParams
|
||||
{
|
||||
CWaveParams()
|
||||
{
|
||||
}
|
||||
|
||||
CWaveParams( const CWaveParams& src )
|
||||
{
|
||||
int c = src.items.Count();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
items.AddToTail( src.items[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
CUtlVector< CWaveFile * > items;
|
||||
};
|
||||
|
||||
int WaveProperties( CWaveParams *params );
|
||||
|
||||
|
||||
#endif // WAVEPROPERTIES_H
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,473 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "workspace.h"
|
||||
#include <KeyValues.h>
|
||||
#include "project.h"
|
||||
#include "vstdlib/random.h"
|
||||
#include "cmdlib.h"
|
||||
#include "FileSystem_Tools.h"
|
||||
#include "utlbuffer.h"
|
||||
#include "workspacemanager.h"
|
||||
#include "workspacebrowser.h"
|
||||
#include "soundbrowser.h"
|
||||
#include "wavebrowser.h"
|
||||
|
||||
CWorkspace::CWorkspace( char const *filename )
|
||||
{
|
||||
m_szVSSUserName[ 0 ] = 0;
|
||||
m_szVSSProject[ 0 ] = 0;
|
||||
|
||||
Q_strncpy( m_szFile, filename, sizeof( m_szFile ) );
|
||||
// By default, name is the same as the filename
|
||||
Q_FileBase( m_szFile, m_szName, sizeof( m_szName ) );
|
||||
m_bDirty = false;
|
||||
LoadFromFile();
|
||||
}
|
||||
|
||||
CWorkspace::~CWorkspace()
|
||||
{
|
||||
while ( m_Projects.Count() > 0 )
|
||||
{
|
||||
CProject *p = m_Projects[ 0 ];
|
||||
m_Projects.Remove( 0 );
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
char const *CWorkspace::GetName() const
|
||||
{
|
||||
return m_szName;
|
||||
}
|
||||
|
||||
bool CWorkspace::IsDirty( void ) const
|
||||
{
|
||||
int c = GetProjectCount();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
CProject *p = GetProject( i );
|
||||
Assert( p );
|
||||
if ( p->IsDirty() )
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_bDirty;
|
||||
}
|
||||
|
||||
void CWorkspace::SetDirty( bool dirty )
|
||||
{
|
||||
m_bDirty = dirty;
|
||||
}
|
||||
|
||||
int CWorkspace::GetProjectCount() const
|
||||
{
|
||||
return m_Projects.Count();
|
||||
}
|
||||
|
||||
CProject *CWorkspace::GetProject( int index ) const
|
||||
{
|
||||
if ( index < 0 || index >= m_Projects.Count() )
|
||||
return NULL;
|
||||
return m_Projects[ index ];
|
||||
}
|
||||
|
||||
void CWorkspace::RemoveProject( CProject *project )
|
||||
{
|
||||
if ( m_Projects.Find( project ) == m_Projects.InvalidIndex() )
|
||||
return;
|
||||
|
||||
m_Projects.FindAndRemove( project );
|
||||
SetDirty( true );
|
||||
}
|
||||
|
||||
|
||||
void CWorkspace::AddProject( CProject *project )
|
||||
{
|
||||
SetDirty( true );
|
||||
|
||||
Assert( m_Projects.Find( project ) == m_Projects.InvalidIndex() );
|
||||
|
||||
m_Projects.AddToTail( project );
|
||||
}
|
||||
|
||||
CProject *CWorkspace::FindProjectFile( char const *filename ) const
|
||||
{
|
||||
int c = GetProjectCount();
|
||||
for ( int i = 0 ; i < c; i++ )
|
||||
{
|
||||
CProject *p = GetProject( i );
|
||||
Assert( p );
|
||||
if ( !Q_stricmp( p->GetFileName(), filename ) )
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CWorkspace::LoadFromFile()
|
||||
{
|
||||
KeyValues *kv = new KeyValues( m_szName );
|
||||
if ( kv->LoadFromFile( filesystem, m_szFile ) )
|
||||
{
|
||||
for ( KeyValues *proj = kv->GetFirstSubKey(); proj; proj = proj->GetNextKey() )
|
||||
{
|
||||
// Add named projects
|
||||
if ( !Q_stricmp( proj->GetName(), "project" ) )
|
||||
{
|
||||
bool expanded = false;
|
||||
char filename[ 256 ];
|
||||
filename[0] = 0;
|
||||
|
||||
for ( KeyValues *sub = proj->GetFirstSubKey(); sub; sub = sub->GetNextKey() )
|
||||
{
|
||||
if ( !Q_stricmp( sub->GetName(), "file" ) )
|
||||
{
|
||||
Q_strcpy( filename, sub->GetString() );
|
||||
continue;
|
||||
}
|
||||
else if ( !Q_stricmp( sub->GetName(), "expanded" ) )
|
||||
{
|
||||
expanded = sub->GetInt() ? true : false;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
CProject *p = new CProject( this, filename );
|
||||
p->SetExpanded( expanded );
|
||||
p->SetDirty( false );
|
||||
m_Projects.AddToTail( p );
|
||||
|
||||
continue;
|
||||
}
|
||||
else if ( !Q_stricmp( proj->GetName(), "vss_username" ) )
|
||||
{
|
||||
SetVSSUserName( proj->GetString() );
|
||||
|
||||
Con_Printf( "VSS User: '%s'\n", GetVSSUserName() );
|
||||
continue;
|
||||
}
|
||||
else if ( !Q_stricmp( proj->GetName(), "vss_project" ) )
|
||||
{
|
||||
SetVSSProject( proj->GetString() );
|
||||
|
||||
Con_Printf( "VSS Project: '%s'\n", GetVSSProject() );
|
||||
continue;
|
||||
}
|
||||
else if ( !Q_stricmp( proj->GetName(), "window" ) )
|
||||
{
|
||||
SetDirty( true );
|
||||
|
||||
char const *windowname = proj->GetString( "windowname", "" );
|
||||
if ( !Q_stricmp( windowname, "workspace" ) )
|
||||
{
|
||||
SceneManager_LoadWindowPositions( proj, GetWorkspaceManager()->GetBrowser() );
|
||||
continue;
|
||||
}
|
||||
else if ( !Q_stricmp( windowname, "soundbrowser" ) )
|
||||
{
|
||||
SceneManager_LoadWindowPositions( proj, GetWorkspaceManager()->GetSoundBrowser() );
|
||||
continue;
|
||||
}
|
||||
else if ( !Q_stricmp( windowname, "wavebrowser" ) )
|
||||
{
|
||||
SceneManager_LoadWindowPositions( proj, GetWorkspaceManager()->GetWaveBrowser() );
|
||||
continue;
|
||||
}
|
||||
else if ( !Q_stricmp( windowname, "main" ) )
|
||||
{
|
||||
SceneManager_LoadWindowPositions( proj, GetWorkspaceManager() );
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
Assert( 0 );
|
||||
}
|
||||
}
|
||||
kv->deleteThis();
|
||||
}
|
||||
|
||||
static void SaveWindowPositions( CUtlBuffer& buf, char const *windowname, mxWindow *wnd )
|
||||
{
|
||||
buf.Printf( "\t\"window\"\n" );
|
||||
buf.Printf( "\t{\n" );
|
||||
buf.Printf( "\t\twindowname\t\"%s\"\n", windowname );
|
||||
|
||||
SceneManager_SaveWindowPositions( buf, 2, wnd );
|
||||
|
||||
buf.Printf( "\t}\n" );
|
||||
}
|
||||
|
||||
void CWorkspace::SaveToFile()
|
||||
{
|
||||
SetDirty( false );
|
||||
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
|
||||
buf.Printf( "%s\n{\n", GetName() );
|
||||
|
||||
// walk projects
|
||||
int c = GetProjectCount();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
CProject *p = GetProject( i );
|
||||
Assert( p );
|
||||
|
||||
buf.Printf( "\t\"project\"\n" );
|
||||
buf.Printf( "\t{\n" );
|
||||
buf.Printf( "\t\t\"expanded\"\t\"%i\"\n", p->IsExpanded() );
|
||||
buf.Printf( "\t\t\"file\"\t\"%s\"\n", p->GetFileName() );
|
||||
buf.Printf( "\t}\n" );
|
||||
|
||||
p->SaveChanges();
|
||||
}
|
||||
|
||||
buf.Printf( "\t\"vss_username\"\t\"%s\"\n", GetVSSUserName() );
|
||||
buf.Printf( "\t\"vss_project\"\t\"%s\"\n", GetVSSProject() );
|
||||
|
||||
// Save window positions
|
||||
SaveWindowPositions( buf, "main", GetWorkspaceManager() );
|
||||
|
||||
SaveWindowPositions( buf, "workspace", GetWorkspaceManager()->GetBrowser() );
|
||||
SaveWindowPositions( buf, "soundbrowser", GetWorkspaceManager()->GetSoundBrowser() );
|
||||
SaveWindowPositions( buf, "wavebrowser", GetWorkspaceManager()->GetWaveBrowser() );
|
||||
|
||||
buf.Printf( "}\n" );
|
||||
|
||||
if ( filesystem->FileExists( m_szFile ) && !filesystem->IsFileWritable( m_szFile ) )
|
||||
{
|
||||
int retval = mxMessageBox( NULL, va( "Check out '%s'?", m_szFile ), g_appTitle, MX_MB_YESNOCANCEL );
|
||||
if ( retval != 0 )
|
||||
return;
|
||||
|
||||
VSS_Checkout( m_szFile );
|
||||
|
||||
if ( !filesystem->IsFileWritable( m_szFile ) )
|
||||
{
|
||||
mxMessageBox( NULL, va( "Unable to check out'%s'!!!", m_szFile ), g_appTitle, MX_MB_OK );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Write it out baby
|
||||
FileHandle_t fh = filesystem->Open( m_szFile, "wt" );
|
||||
if (fh)
|
||||
{
|
||||
filesystem->Write( buf.Base(), buf.TellPut(), fh );
|
||||
filesystem->Close(fh);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( "CWorkspace::SaveToFile: Unable to write file %s!!!\n", m_szFile );
|
||||
}
|
||||
}
|
||||
|
||||
void CWorkspace::SaveChanges()
|
||||
{
|
||||
if ( !IsDirty() )
|
||||
return;
|
||||
|
||||
SaveToFile();
|
||||
}
|
||||
|
||||
|
||||
void CWorkspace::ValidateTree( mxTreeView *tree, mxTreeViewItem *parent )
|
||||
{
|
||||
CUtlVector< mxTreeViewItem * > m_KnownItems;
|
||||
|
||||
int c = GetProjectCount();
|
||||
CProject *proj;
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
proj = GetProject( i );
|
||||
if ( !proj )
|
||||
continue;
|
||||
|
||||
char sz[ 256 ];
|
||||
if ( proj->GetComments() && proj->GetComments()[0] )
|
||||
{
|
||||
Q_snprintf( sz, sizeof( sz ), "%s : %s", proj->GetName(), proj->GetComments() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( sz, proj->GetName(), sizeof( sz ) );
|
||||
}
|
||||
|
||||
mxTreeViewItem *spot = proj->FindItem( tree, parent );
|
||||
if ( !spot )
|
||||
{
|
||||
spot = tree->add( parent, sz );
|
||||
}
|
||||
|
||||
m_KnownItems.AddToTail( spot );
|
||||
|
||||
proj->SetOrdinal ( i );
|
||||
|
||||
tree->setLabel( spot, sz );
|
||||
|
||||
tree->setImages( spot, proj->GetIconIndex(), proj->GetIconIndex() );
|
||||
tree->setUserData( spot, proj );
|
||||
//tree->setOpen( spot, proj->IsExpanded() );
|
||||
|
||||
proj->ValidateTree( tree, spot );
|
||||
}
|
||||
|
||||
// Now check for dangling items
|
||||
mxTreeViewItem *start = tree->getFirstChild( parent );
|
||||
while ( start )
|
||||
{
|
||||
mxTreeViewItem *next = tree->getNextChild( start );
|
||||
|
||||
if ( m_KnownItems.Find( start ) == m_KnownItems.InvalidIndex() )
|
||||
{
|
||||
tree->remove( start );
|
||||
}
|
||||
|
||||
start = next;
|
||||
}
|
||||
|
||||
tree->sortTree( parent, true, CWorkspaceBrowser::CompareFunc, 0 );
|
||||
}
|
||||
|
||||
bool CWorkspace::CanClose( void )
|
||||
{
|
||||
if ( !IsDirty() )
|
||||
return true;
|
||||
|
||||
int retval = mxMessageBox( NULL, va( "Save changes to workspace '%s'?", GetName() ), g_appTitle, MX_MB_YESNOCANCEL );
|
||||
if ( retval == 2 )
|
||||
return false;
|
||||
|
||||
if ( retval == 0 )
|
||||
{
|
||||
SaveChanges();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char const *CWorkspace::GetVSSUserName() const
|
||||
{
|
||||
return m_szVSSUserName;
|
||||
}
|
||||
|
||||
char const *CWorkspace::GetVSSProject() const
|
||||
{
|
||||
return m_szVSSProject;
|
||||
}
|
||||
|
||||
void CWorkspace::SetVSSUserName( char const *username )
|
||||
{
|
||||
Q_strncpy( m_szVSSUserName, username, sizeof( m_szVSSUserName ) );
|
||||
}
|
||||
|
||||
void CWorkspace::SetVSSProject( char const *projectname )
|
||||
{
|
||||
Q_strncpy( m_szVSSProject, projectname, sizeof( m_szVSSProject ) );
|
||||
while ( Q_strlen( m_szVSSProject ) > 0 )
|
||||
{
|
||||
if ( m_szVSSProject[ Q_strlen( m_szVSSProject ) - 1 ] == '/' ||
|
||||
m_szVSSProject[ Q_strlen( m_szVSSProject ) - 1 ] == '\\' )
|
||||
{
|
||||
m_szVSSProject[ Q_strlen( m_szVSSProject ) - 1 ] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWorkspace::Checkout( bool updatestateicons /*= true*/ )
|
||||
{
|
||||
VSS_Checkout( GetFileName(), updatestateicons );
|
||||
}
|
||||
|
||||
void CWorkspace::Checkin(bool updatestateicons /*= true*/)
|
||||
{
|
||||
VSS_Checkin( GetFileName(), updatestateicons );
|
||||
}
|
||||
|
||||
bool CWorkspace::IsCheckedOut() const
|
||||
{
|
||||
return filesystem->IsFileWritable( GetFileName() );
|
||||
}
|
||||
|
||||
int CWorkspace::GetIconIndex() const
|
||||
{
|
||||
if ( IsCheckedOut() )
|
||||
{
|
||||
return IMAGE_WORKSPACE_CHECKEDOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IMAGE_WORKSPACE;
|
||||
}
|
||||
}
|
||||
|
||||
void CWorkspace::MoveChildUp( ITreeItem *child )
|
||||
{
|
||||
int c = GetProjectCount();
|
||||
for ( int i = 1; i < c; i++ )
|
||||
{
|
||||
CProject *p = GetProject( i );
|
||||
if ( p != child )
|
||||
continue;
|
||||
|
||||
CProject *prev = GetProject( i - 1 );
|
||||
// Swap
|
||||
m_Projects[ i - 1 ] = p;
|
||||
m_Projects[ i ] = prev;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CWorkspace::MoveChildDown( ITreeItem *child )
|
||||
{
|
||||
int c = GetProjectCount();
|
||||
for ( int i = 0; i < c - 1; i++ )
|
||||
{
|
||||
CProject *p = GetProject( i );
|
||||
if ( p != child )
|
||||
continue;
|
||||
|
||||
CProject *next = GetProject( i + 1 );
|
||||
// Swap
|
||||
m_Projects[ i ] = next;
|
||||
m_Projects[ i + 1 ] = p;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool CWorkspace::IsChildFirst( ITreeItem *child )
|
||||
{
|
||||
int idx = m_Projects.Find( (CProject *)child );
|
||||
if ( idx == m_Projects.InvalidIndex() )
|
||||
return false;
|
||||
|
||||
if ( idx != 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWorkspace::IsChildLast( ITreeItem *child )
|
||||
{
|
||||
int idx = m_Projects.Find( (CProject *)child );
|
||||
if ( idx == m_Projects.InvalidIndex() )
|
||||
return false;
|
||||
|
||||
if ( idx != m_Projects.Count() - 1 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef WORKSPACE_H
|
||||
#define WORKSPACE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CProject;
|
||||
class mxTreeView;
|
||||
|
||||
#include "itreeitem.h"
|
||||
|
||||
class CWorkspace : public ITreeItem
|
||||
{
|
||||
public:
|
||||
CWorkspace( char const *filename );
|
||||
~CWorkspace();
|
||||
|
||||
char const *GetName() const;
|
||||
char const *GetFileName() const { return m_szFile; }
|
||||
|
||||
bool IsDirty( void ) const;
|
||||
void SetDirty( bool dirty );
|
||||
|
||||
int GetProjectCount() const;
|
||||
CProject *GetProject( int index ) const;
|
||||
void AddProject( CProject *project );
|
||||
CProject *FindProjectFile( char const *filename ) const;
|
||||
void RemoveProject( CProject *project );
|
||||
|
||||
void ValidateTree( mxTreeView *tree, mxTreeViewItem *parent );
|
||||
|
||||
bool CanClose( void );
|
||||
|
||||
void SaveChanges();
|
||||
|
||||
virtual CWorkspace *GetWorkspace() { return this; }
|
||||
virtual CProject *GetProject() { return NULL; }
|
||||
virtual CScene *GetScene() { return NULL; }
|
||||
virtual CVCDFile *GetVCDFile() { return NULL; }
|
||||
virtual CSoundEntry *GetSoundEntry() { return NULL; }
|
||||
virtual CWaveFile *GetWaveFile() { return NULL; }
|
||||
|
||||
|
||||
char const *GetVSSUserName() const;
|
||||
char const *GetVSSProject() const;
|
||||
|
||||
void SetVSSUserName( char const *username );
|
||||
void SetVSSProject( char const *projectname );
|
||||
|
||||
virtual void Checkout( bool updatestateicons = true );
|
||||
virtual void Checkin( bool updatestateicons = true );
|
||||
|
||||
bool IsCheckedOut() const;
|
||||
int GetIconIndex() const;
|
||||
|
||||
virtual void MoveChildUp( ITreeItem *item );
|
||||
virtual void MoveChildDown( ITreeItem *item );
|
||||
|
||||
virtual bool IsChildFirst( ITreeItem *child );
|
||||
virtual bool IsChildLast( ITreeItem *child );
|
||||
|
||||
private:
|
||||
|
||||
void LoadFromFile();
|
||||
void SaveToFile();
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_WORKSPACE_NAME = 128,
|
||||
MAX_WORKSPACE_FILENAME = 256
|
||||
};
|
||||
|
||||
char m_szName[ MAX_WORKSPACE_NAME ];
|
||||
char m_szFile[ MAX_WORKSPACE_FILENAME ];
|
||||
|
||||
char m_szVSSUserName[ MAX_WORKSPACE_NAME ];
|
||||
char m_szVSSProject[ MAX_WORKSPACE_NAME ];
|
||||
|
||||
bool m_bDirty;
|
||||
|
||||
CUtlVector< CProject * > m_Projects;
|
||||
};
|
||||
|
||||
#endif // WORKSPACE_H
|
||||
@@ -0,0 +1,258 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "workspacebrowser.h"
|
||||
#include "workspace.h"
|
||||
#include "project.h"
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
#include "project.h"
|
||||
#include "vcdfile.h"
|
||||
#include "soundentry.h"
|
||||
#include "scene.h"
|
||||
#include "workspacemanager.h"
|
||||
|
||||
enum
|
||||
{
|
||||
IDC_WSB_TREE = 101,
|
||||
};
|
||||
|
||||
class CBrowserTree : public mxTreeView
|
||||
{
|
||||
public:
|
||||
CBrowserTree( mxWindow *parent, int id = 0 )
|
||||
: mxTreeView( parent, 0, 0, 0, 0, id )
|
||||
{
|
||||
// SendMessage ( (HWND)getHandle(), WM_SETFONT, (WPARAM) (HFONT) GetStockObject (ANSI_FIXED_FONT), MAKELPARAM (TRUE, 0));
|
||||
}
|
||||
};
|
||||
|
||||
int CALLBACK CWorkspaceBrowser::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
|
||||
{
|
||||
ITreeItem const *item1 = (ITreeItem *)lParam1;
|
||||
ITreeItem const *item2 = (ITreeItem *)lParam2;
|
||||
|
||||
Assert( item1 && item2 );
|
||||
|
||||
if ( item1->GetOrdinal() < item2->GetOrdinal() )
|
||||
return -1;
|
||||
else if ( item1->GetOrdinal() > item2->GetOrdinal() )
|
||||
return 1;
|
||||
|
||||
// Ok, just compare pointers... sigh
|
||||
return ( item1 < item2 ) ? -1 : 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *parent -
|
||||
//-----------------------------------------------------------------------------
|
||||
CWorkspaceBrowser::CWorkspaceBrowser( mxWindow *parent, CWorkspaceManager *manager, int id ) :
|
||||
BaseClass( parent, 0, 0, 0, 0, "Workspace Browser", id )
|
||||
{
|
||||
m_pManager = manager;
|
||||
|
||||
SceneManager_MakeToolWindow( this, false );
|
||||
|
||||
m_pLastSelected = NULL;
|
||||
|
||||
m_pCurrentWorkspace = NULL;
|
||||
m_pTree = new CBrowserTree( this, IDC_WSB_TREE );
|
||||
|
||||
HIMAGELIST list = GetWorkspaceManager()->CreateImageList();
|
||||
|
||||
// Associate the image list with the tree-view control.
|
||||
m_pTree->setImageList( (void *)list );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *event -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CWorkspaceBrowser::handleEvent( mxEvent *event )
|
||||
{
|
||||
int iret = 0;
|
||||
switch ( event->event )
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case mxEvent::Action:
|
||||
{
|
||||
switch ( event->action )
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case IDC_WSB_TREE:
|
||||
{
|
||||
iret = 1;
|
||||
|
||||
bool rightmouse = ( event->flags == mxEvent::RightClicked ) ? true : false;
|
||||
bool doubleclicked = ( event->flags == mxEvent::DoubleClicked ) ? true : false;
|
||||
|
||||
OnTreeItemSelected( event->x, event->y, rightmouse, doubleclicked );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case mxEvent::Size:
|
||||
{
|
||||
m_pTree->setBounds( 0, 0, w2(), h2() );
|
||||
|
||||
GetWorkspaceManager()->SetWorkspaceDirty();
|
||||
|
||||
iret = 1;
|
||||
}
|
||||
break;
|
||||
case mxEvent::Close:
|
||||
{
|
||||
iret = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return iret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : CWorkspace
|
||||
//-----------------------------------------------------------------------------
|
||||
CWorkspace *CWorkspaceBrowser::GetWorkspace()
|
||||
{
|
||||
return m_pCurrentWorkspace;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWorkspaceBrowser::PopulateTree()
|
||||
{
|
||||
m_pLastSelected = NULL;
|
||||
|
||||
CWorkspace *w = m_pCurrentWorkspace;
|
||||
|
||||
if ( !w )
|
||||
return;
|
||||
|
||||
// Add root element
|
||||
char sz[ 128 ];
|
||||
if ( w->GetProjectCount() == 1 )
|
||||
{
|
||||
Q_snprintf( sz, sizeof( sz ), "Workspace '%s': %i project", w->GetName(), w->GetProjectCount() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( sz, sizeof( sz ), "Workspace '%s': %i projects", w->GetName(), w->GetProjectCount() );
|
||||
}
|
||||
|
||||
|
||||
mxTreeViewItem *root = w->FindItem( m_pTree, NULL );
|
||||
if ( !root )
|
||||
{
|
||||
root = m_pTree->add( NULL, sz );
|
||||
}
|
||||
|
||||
// Reset the label
|
||||
m_pTree->setLabel( root, sz );
|
||||
|
||||
m_pTree->setImages( root, w->GetIconIndex(), w->GetIconIndex() );
|
||||
m_pTree->setUserData( root, w );
|
||||
|
||||
w->ValidateTree( m_pTree, root );
|
||||
|
||||
m_pTree->setOpen( root, true );
|
||||
|
||||
m_pTree->sortTree( root, true, CompareFunc, 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *w -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWorkspaceBrowser::SetWorkspace( CWorkspace *w )
|
||||
{
|
||||
m_pCurrentWorkspace = w;
|
||||
|
||||
PopulateTree();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *project -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CWorkspaceBrowser::AddProject( CProject *project )
|
||||
{
|
||||
if ( !m_pCurrentWorkspace )
|
||||
return;
|
||||
|
||||
m_pCurrentWorkspace->AddProject( project );
|
||||
|
||||
PopulateTree();
|
||||
}
|
||||
|
||||
ITreeItem *CWorkspaceBrowser::GetSelectedItem()
|
||||
{
|
||||
return m_pLastSelected;
|
||||
}
|
||||
|
||||
CWorkspaceManager *CWorkspaceBrowser::GetManager()
|
||||
{
|
||||
return m_pManager;
|
||||
}
|
||||
|
||||
void CWorkspaceBrowser::OnTreeItemSelected( int x, int y, bool rightmouse, bool doubleclick )
|
||||
{
|
||||
mxTreeViewItem *item = m_pTree->getSelectedItem();
|
||||
if ( !item )
|
||||
{
|
||||
Con_Printf( "No item selected\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
ITreeItem *p = (ITreeItem *)m_pTree->getUserData( item );
|
||||
if ( !p )
|
||||
{
|
||||
Con_Printf( "No userdata for item\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
m_pLastSelected = p;
|
||||
|
||||
GetManager()->UpdateMenus();
|
||||
|
||||
if ( p->GetSoundEntry() || p->GetWaveFile() )
|
||||
{
|
||||
GetManager()->OnSoundShowInBrowsers();
|
||||
}
|
||||
|
||||
if ( !rightmouse )
|
||||
{
|
||||
if ( doubleclick )
|
||||
{
|
||||
GetManager()->OnDoubleClicked( GetSelectedItem() );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
POINT pt;
|
||||
GetCursorPos( &pt );
|
||||
|
||||
ScreenToClient( (HWND)GetManager()->getHandle(), &pt );
|
||||
|
||||
GetManager()->ShowContextMenu( pt.x, pt.y, GetSelectedItem() );
|
||||
}
|
||||
|
||||
void CWorkspaceBrowser::JumpTo( ITreeItem *item )
|
||||
{
|
||||
mxTreeViewItem *found = item->FindItem( m_pTree, NULL, true );
|
||||
if ( found )
|
||||
{
|
||||
m_pTree->scrollTo( found );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef WORKSPACEBROWSER_H
|
||||
#define WORKSPACEBROWSER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "mxtk/mxTreeView.h"
|
||||
#include "commctrl.h"
|
||||
|
||||
class CWorkspace;
|
||||
class CProject;
|
||||
class CScene;
|
||||
class CVCDFile;
|
||||
class CSoundEntry;
|
||||
|
||||
class CBrowserTree;
|
||||
class ITreeItem;
|
||||
class CWorkspaceManager;
|
||||
|
||||
class CWorkspaceBrowser : public mxWindow
|
||||
{
|
||||
typedef mxWindow BaseClass;
|
||||
public:
|
||||
|
||||
CWorkspaceBrowser( mxWindow *parent, CWorkspaceManager *manager, int id );
|
||||
|
||||
CWorkspace *GetWorkspace();
|
||||
void SetWorkspace( CWorkspace *w );
|
||||
void AddProject( CProject *project );
|
||||
|
||||
virtual int handleEvent( mxEvent *event );
|
||||
|
||||
ITreeItem *GetSelectedItem();
|
||||
|
||||
void PopulateTree();
|
||||
|
||||
static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
|
||||
|
||||
|
||||
void JumpTo( ITreeItem *item );
|
||||
|
||||
private:
|
||||
|
||||
CWorkspaceManager *GetManager();
|
||||
|
||||
void OnTreeItemSelected( int x, int y, bool rightmouse, bool doubleclick );
|
||||
|
||||
CWorkspace *m_pCurrentWorkspace;
|
||||
|
||||
CBrowserTree *m_pTree;
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_BITMAPS = 12,
|
||||
};
|
||||
|
||||
ITreeItem *m_pLastSelected;
|
||||
CWorkspaceManager *m_pManager;
|
||||
};
|
||||
|
||||
#endif // WORKSPACEBROWSER_H
|
||||
@@ -0,0 +1,184 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef WORKSPACEMANAGER_H
|
||||
#define WORKSPACEMANAGER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CWorkspaceBrowser;
|
||||
class CWorkspaceWorkArea;
|
||||
class CWorkspace;
|
||||
class CProject;
|
||||
class CScene;
|
||||
class CVCDFile;
|
||||
class CSoundEntry;
|
||||
class ITreeItem;
|
||||
class CSoundBrowser;
|
||||
class CWaveBrowser;
|
||||
class CWaveFile;
|
||||
|
||||
struct _IMAGELIST;
|
||||
typedef struct _IMAGELIST NEAR* HIMAGELIST;
|
||||
|
||||
enum
|
||||
{
|
||||
IMAGE_WORKSPACE = 0,
|
||||
IMAGE_WORKSPACE_CHECKEDOUT,
|
||||
IMAGE_PROJECT,
|
||||
IMAGE_PROJECT_CHECKEDOUT,
|
||||
IMAGE_SCENE,
|
||||
// IMAGE_SCENE_CHECKEDOUT,
|
||||
IMAGE_VCD,
|
||||
IMAGE_VCD_CHECKEDOUT,
|
||||
IMAGE_WAV,
|
||||
IMAGE_WAV_CHECKEDOUT,
|
||||
IMAGE_SPEAK,
|
||||
IMAGE_SPEAK_CHECKEDOUT,
|
||||
|
||||
NUM_IMAGES,
|
||||
};
|
||||
|
||||
class CWorkspaceManager : public mxWindow
|
||||
{
|
||||
public:
|
||||
CWorkspaceManager();
|
||||
~CWorkspaceManager();
|
||||
|
||||
virtual int handleEvent( mxEvent *event );
|
||||
|
||||
CWorkspaceBrowser *GetBrowser();
|
||||
CSoundBrowser *GetSoundBrowser();
|
||||
CWaveBrowser *GetWaveBrowser();
|
||||
void LoadWorkspace( char const *filename );
|
||||
|
||||
void AutoLoad( char const *workspace );
|
||||
|
||||
void ShowContextMenu( int x, int y, ITreeItem *item );
|
||||
void OnDoubleClicked( ITreeItem *item );
|
||||
|
||||
void UpdateMenus();
|
||||
|
||||
virtual bool Closing();
|
||||
|
||||
HIMAGELIST CreateImageList();
|
||||
|
||||
void RefreshBrowsers();
|
||||
|
||||
void OnSoundShowInBrowsers();
|
||||
|
||||
void SetWorkspaceDirty();
|
||||
|
||||
int GetLanguageId() const;
|
||||
|
||||
private:
|
||||
|
||||
void PerformLayout( bool movebrowsers );
|
||||
|
||||
void Think( float dt );
|
||||
void Frame( void );
|
||||
|
||||
virtual void OnDelete();
|
||||
|
||||
void SetWorkspace( CWorkspace *ws );
|
||||
void OnUpdateTitle( void );
|
||||
|
||||
void CreateFileMenu( mxMenu *m );
|
||||
void CreateProjectMenu( mxMenu *m );
|
||||
|
||||
int GetMaxRecentFiles( void ) const;
|
||||
|
||||
// Workspace message handlers
|
||||
void OnNewWorkspace();
|
||||
void OnOpenWorkspace();
|
||||
void OnCloseWorkspace();
|
||||
void OnSaveWorkspace();
|
||||
|
||||
void OnChangeVSSProperites();
|
||||
|
||||
void OnCheckoutWorkspace();
|
||||
void OnCheckinWorkspace();
|
||||
|
||||
// Project message handlers
|
||||
void OnNewProject();
|
||||
void OnInsertProject();
|
||||
void OnRemoveProject();
|
||||
void OnModifyProjectComments();
|
||||
|
||||
// Scene message handlers
|
||||
void OnNewScene();
|
||||
void OnModifySceneComments();
|
||||
void OnRemoveScene();
|
||||
|
||||
// Sound entry handlers
|
||||
void OnSoundPlay();
|
||||
void OnSoundToggleVoiceDuck();
|
||||
void OnSoundEditText();
|
||||
|
||||
void OnSoundProperties();
|
||||
void OnWaveProperties();
|
||||
|
||||
void OnCheckout();
|
||||
void OnCheckin();
|
||||
|
||||
void OnMoveUp();
|
||||
void OnMoveDown();
|
||||
|
||||
//void OnSoundCheckOut();
|
||||
//void OnSoundCheckIn();
|
||||
|
||||
// Scene entries
|
||||
void OnSceneAddVCD();
|
||||
void OnSceneRemoveVCD();
|
||||
void OnModifyVCDComments();
|
||||
|
||||
void OnRecentWorkspace( int index );
|
||||
void OnChangeLanguage( int lang_index, bool force = false );
|
||||
void AddFileToRecentWorkspaceList( char const *filename );
|
||||
void UpdateRecentFilesMenu();
|
||||
|
||||
void LoadRecentFilesMenuFromDisk();
|
||||
void SaveRecentFilesMenuToDisk();
|
||||
|
||||
|
||||
bool CloseWorkspace();
|
||||
|
||||
void ShowContextMenu_Workspace( int x, int y, CWorkspace *ws );
|
||||
void ShowContextMenu_Project( int x, int y, CProject *project );
|
||||
void ShowContextMenu_Scene( int x, int y, CScene *scene );
|
||||
void ShowContextMenu_VCD( int x, int y, CVCDFile *vcd );
|
||||
void ShowContextMenu_SoundEntry( int x, int y, CSoundEntry *entry );
|
||||
void ShowContextMenu_WaveFile( int x, int y, CWaveFile *entry );
|
||||
|
||||
mxMenuBar *m_pMenuBar;
|
||||
|
||||
mxMenu *m_pFileMenu;
|
||||
mxMenu *m_pRecentFileMenu;
|
||||
int m_nRecentMenuItems;
|
||||
mxMenu *m_pProjectMenu;
|
||||
mxMenu *m_pOptionsMenu;
|
||||
mxMenu *m_pMenuCloseCaptionLanguages;
|
||||
|
||||
CWorkspaceWorkArea *m_pWorkArea;
|
||||
|
||||
CWorkspaceBrowser *m_pBrowser;
|
||||
CSoundBrowser *m_pSoundBrowser;
|
||||
CWaveBrowser *m_pWaveBrowser;
|
||||
|
||||
struct RecentFile
|
||||
{
|
||||
char filename[ 256 ];
|
||||
};
|
||||
|
||||
CUtlVector< RecentFile > m_RecentFiles;
|
||||
int m_nLanguageId;
|
||||
long m_lEnglishCaptionsFileChangeTime;
|
||||
};
|
||||
|
||||
CWorkspaceManager *GetWorkspaceManager();
|
||||
|
||||
#endif // WORKSPACEMANAGER_H
|
||||