|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// SHOW_SOUNDS.CPP
//
// Show Sounds Display.
//=====================================================================================//
#include "vxconsole.h"
#define ID_SHOWSOUNDS_LISTVIEW 100
// column id
#define ID_SS_NAME 0
#define ID_SS_PREFIX 1
#define ID_SS_FORMAT 2
#define ID_SS_RATE 3
#define ID_SS_BITS 4
#define ID_SS_CHANNELS 5
#define ID_SS_SIZE 6
#define ID_SS_STREAMED 7
#define ID_SS_LOOPED 8
#define ID_SS_LENGTH 9
typedef struct { int listIndex; char *pName; char *pPrefix; char *pFormat; int rate; char rateBuff[16]; int bits; char bitsBuff[16]; int channels; char channelsBuff[16]; int numSamples; int dataSize; char dataSizeBuff[16]; int streamed; char streamedBuff[16]; int looped; char loopedBuff[16]; float length; char lengthBuff[16]; } sound_t;
typedef struct { const CHAR* name; int width; int subItemIndex; CHAR nameBuff[32]; } label_t;
HWND g_showSounds_hWnd; HWND g_showSounds_hWndListView; RECT g_showSounds_windowRect; int g_showSounds_sortColumn; int g_showSounds_sortDescending; sound_t *g_showSounds_pSounds; int g_showSounds_numSounds; int g_showSounds_currentFrame;
label_t g_showSounds_Labels[] = { {"Name", 300, ID_SS_NAME}, {"Prefix", 80, ID_SS_PREFIX}, {"Format", 80, ID_SS_FORMAT}, {"Rate", 80, ID_SS_RATE}, {"Bits", 80, ID_SS_BITS}, {"Channels", 80, ID_SS_CHANNELS}, {"Size", 80, ID_SS_SIZE}, {"Streamed", 80, ID_SS_STREAMED}, {"Looped", 80, ID_SS_LOOPED}, {"Length", 80, ID_SS_LENGTH}, };
//-----------------------------------------------------------------------------
// ShowSounds_SaveConfig
//
//-----------------------------------------------------------------------------
void ShowSounds_SaveConfig() { char buff[256];
Sys_SetRegistryInteger( "showSoundsSortColumn", g_showSounds_sortColumn ); Sys_SetRegistryInteger( "showSoundsSortDescending", g_showSounds_sortDescending );
WINDOWPLACEMENT wp; memset( &wp, 0, sizeof( wp ) ); wp.length = sizeof( WINDOWPLACEMENT ); GetWindowPlacement( g_showSounds_hWnd, &wp ); g_showSounds_windowRect = wp.rcNormalPosition;
sprintf( buff, "%d %d %d %d", g_showSounds_windowRect.left, g_showSounds_windowRect.top, g_showSounds_windowRect.right, g_showSounds_windowRect.bottom ); Sys_SetRegistryString( "showSoundsWindowRect", buff ); }
//-----------------------------------------------------------------------------
// ShowSounds_LoadConfig
//
//-----------------------------------------------------------------------------
void ShowSounds_LoadConfig() { int numArgs; char buff[256];
Sys_GetRegistryInteger( "showSoundsSortColumn", ID_SS_NAME, g_showSounds_sortColumn ); Sys_GetRegistryInteger( "showSoundsSortDescending", false, g_showSounds_sortDescending );
Sys_GetRegistryString( "showSoundsWindowRect", buff, "", sizeof( buff ) ); numArgs = sscanf( buff, "%d %d %d %d", &g_showSounds_windowRect.left, &g_showSounds_windowRect.top, &g_showSounds_windowRect.right, &g_showSounds_windowRect.bottom ); if ( numArgs != 4 || g_showSounds_windowRect.left < 0 || g_showSounds_windowRect.top < 0 || g_showSounds_windowRect.right < 0 || g_showSounds_windowRect.bottom < 0 ) memset( &g_showSounds_windowRect, 0, sizeof( g_showSounds_windowRect ) ); }
//-----------------------------------------------------------------------------
// ShowSounds_Clear
//
//-----------------------------------------------------------------------------
void ShowSounds_Clear() { // delete all the list view entries
if ( g_showSounds_hWnd ) ListView_DeleteAllItems( g_showSounds_hWndListView );
if ( !g_showSounds_pSounds ) return;
for ( int i=0; i<g_showSounds_numSounds; i++ ) { free( g_showSounds_pSounds[i].pName ); free( g_showSounds_pSounds[i].pPrefix ); free( g_showSounds_pSounds[i].pFormat ); }
g_showSounds_pSounds = NULL; g_showSounds_numSounds = 0; }
//-----------------------------------------------------------------------------
// ShowSounds_Export
//
//-----------------------------------------------------------------------------
void ShowSounds_Export() { }
//-----------------------------------------------------------------------------
// ShowSounds_Summary
//
//-----------------------------------------------------------------------------
void ShowSounds_Summary() { char buff[1024];
// tally the totals
int totalStreamed = 0; int totalStatic = 0; for ( int i=0; i<g_showSounds_numSounds; i++ ) { if ( g_showSounds_pSounds[i].streamed ) { totalStreamed += g_showSounds_pSounds[i].dataSize; } else { totalStatic += g_showSounds_pSounds[i].dataSize; } }
sprintf( buff, "Entries:\t\t\t%d\n" "Static Memory:\t\t%.2f MB\n" "Streamed Memory:\t\t%.2f MB\n", g_showSounds_numSounds, ( float )totalStatic/( 1024.0F*1024.0F ), ( float )totalStreamed/( 1024.0F*1024.0F ) );
MessageBox( g_showSounds_hWnd, buff, "Sound Summary", MB_OK|MB_APPLMODAL ); }
//-----------------------------------------------------------------------------
// ShowSounds_Play
//
//-----------------------------------------------------------------------------
void ShowSounds_Play() { char command[256]; sound_t* pSound; int selection; LVITEM lvitem;
if ( !g_connectedToApp ) return;
selection = ListView_GetSelectionMark( g_showSounds_hWndListView ); if ( selection == -1 ) return;
memset( &lvitem, 0, sizeof( lvitem ) ); lvitem.mask = LVIF_PARAM; lvitem.iItem = selection; ListView_GetItem( g_showSounds_hWndListView, &lvitem );
pSound = ( sound_t* )lvitem.lParam;
sprintf( command, "play %s%s", pSound->pPrefix, pSound->pName );
// send the command to application
ProcessCommand( command ); }
//-----------------------------------------------------------------------------
// ShowSounds_CompareFunc
//
//-----------------------------------------------------------------------------
int CALLBACK ShowSounds_CompareFunc( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ) { sound_t* pSoundA = ( sound_t* )lParam1; sound_t* pSoundB = ( sound_t* )lParam2;
int sort = 0; switch ( g_showSounds_sortColumn ) { case ID_SS_NAME: sort = stricmp( pSoundA->pName, pSoundB->pName ); break;
case ID_SS_PREFIX: sort = stricmp( pSoundA->pPrefix, pSoundB->pPrefix ); break;
case ID_SS_FORMAT: sort = stricmp( pSoundA->pFormat, pSoundB->pFormat ); break;
case ID_SS_RATE: sort = pSoundA->rate - pSoundB->rate; break; case ID_SS_BITS: sort = pSoundA->bits - pSoundB->bits; break;
case ID_SS_CHANNELS: sort = stricmp( pSoundA->channelsBuff, pSoundB->channelsBuff ); break;
case ID_SS_SIZE: sort = pSoundA->dataSize - pSoundB->dataSize; break;
case ID_SS_STREAMED: sort = stricmp( pSoundA->streamedBuff, pSoundB->streamedBuff ); break;
case ID_SS_LOOPED: sort = stricmp( pSoundA->loopedBuff, pSoundB->loopedBuff ); break;
case ID_SS_LENGTH: if ( pSoundA->length < pSoundB->length ) sort = -1; else if ( pSoundA->length == pSoundB->length ) sort = 0; else sort = 1; break; }
// flip the sort order
if ( g_showSounds_sortDescending ) sort *= -1;
return ( sort ); }
//-----------------------------------------------------------------------------
// ShowSounds_SortItems
//
//-----------------------------------------------------------------------------
void ShowSounds_SortItems() { LVITEM lvitem; sound_t *pSound; int i;
if ( !g_showSounds_hWnd ) { // only sort if window is visible
return; }
ListView_SortItems( g_showSounds_hWndListView, ShowSounds_CompareFunc, 0 );
memset( &lvitem, 0, sizeof( lvitem ) ); lvitem.mask = LVIF_PARAM;
// get each item and reset its list index
int itemCount = ListView_GetItemCount( g_showSounds_hWndListView ); for ( i=0; i<itemCount; i++ ) { lvitem.iItem = i; ListView_GetItem( g_showSounds_hWndListView, &lvitem );
pSound = ( sound_t* )lvitem.lParam; pSound->listIndex = i; }
// update list view columns with sort key
for ( i=0; i<sizeof( g_showSounds_Labels )/sizeof( g_showSounds_Labels[0] ); i++ ) { char symbol; LVCOLUMN lvc;
if ( i == g_showSounds_sortColumn ) symbol = g_showSounds_sortDescending ? '<' : '>'; else symbol = ' '; sprintf( g_showSounds_Labels[i].nameBuff, "%s %c", g_showSounds_Labels[i].name, symbol );
memset( &lvc, 0, sizeof( lvc ) ); lvc.mask = LVCF_TEXT; lvc.pszText = ( LPSTR )g_showSounds_Labels[i].nameBuff;
ListView_SetColumn( g_showSounds_hWndListView, i, &lvc ); } }
//-----------------------------------------------------------------------------
// ShowSounds_AddViewItem
//
//-----------------------------------------------------------------------------
void ShowSounds_AddViewItem( sound_t* pSound ) { LVITEM lvi;
if ( !g_showSounds_hWnd ) { // only valid if log window is visible
return; }
// update the text callback buffers
if ( pSound->rate >= 0 ) sprintf( pSound->rateBuff, "%5.2f KHz", ( float )pSound->rate/1000.0f ); else strcpy( pSound->rateBuff, "???" );
if ( pSound->bits >= 0 ) sprintf( pSound->bitsBuff, "%d", pSound->bits ); else strcpy( pSound->bitsBuff, "???" );
if ( pSound->channels >= 1 ) strcpy( pSound->channelsBuff, pSound->channels == 2 ? "Stereo" : "Mono" ); else strcpy( pSound->channelsBuff, "???" );
if ( pSound->dataSize >= 0 ) sprintf( pSound->dataSizeBuff, "%d", pSound->dataSize ); else strcpy( pSound->dataSizeBuff, "???" );
if ( pSound->streamed >= 0 ) strcpy( pSound->streamedBuff, pSound->streamed ? "Stream" : "Static" ); else strcpy( pSound->streamedBuff, "???" );
if ( pSound->looped >= 0 ) strcpy( pSound->loopedBuff, pSound->looped ? "Looped" : "One-Shot" ); else strcpy( pSound->loopedBuff, "???" );
sprintf( pSound->lengthBuff, "%2.2d:%2.2d:%3.3d", ( int )pSound->length/60, ( int )pSound->length%60, ( int )( 1000*( pSound->length-( int )pSound->length ) )%1000 );
int itemCount = ListView_GetItemCount( g_showSounds_hWndListView );
// setup and insert at end of list
memset( &lvi, 0, sizeof( lvi ) ); lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; lvi.iItem = itemCount; lvi.iSubItem = 0; lvi.state = 0; lvi.stateMask = 0; lvi.pszText = LPSTR_TEXTCALLBACK; lvi.lParam = ( LPARAM )pSound; // insert and set the real index
pSound->listIndex = ListView_InsertItem( g_showSounds_hWndListView, &lvi ); }
//-----------------------------------------------------------------------------
// ShowSounds_Refresh
//
//-----------------------------------------------------------------------------
void ShowSounds_Refresh() { char command[256];
strcpy( command, "vx_soundlist" );
// send the command to application which replies with list data
if ( g_connectedToApp ) ProcessCommand( command ); }
//-----------------------------------------------------------------------------
// ShowSounds_SizeWindow
//
//-----------------------------------------------------------------------------
void ShowSounds_SizeWindow( HWND hwnd, int cx, int cy ) { if ( cx==0 || cy==0 ) { RECT rcClient; GetClientRect( hwnd, &rcClient ); cx = rcClient.right; cy = rcClient.bottom; }
// position the ListView
SetWindowPos( g_showSounds_hWndListView, NULL, 0, 0, cx, cy, SWP_NOZORDER ); }
//-----------------------------------------------------------------------------
// ShowSounds_WndProc
//
//-----------------------------------------------------------------------------
LRESULT CALLBACK ShowSounds_WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { WORD wID = LOWORD( wParam ); sound_t* pSound;
switch ( message ) { case WM_CREATE: return 0L;
case WM_DESTROY: ShowSounds_SaveConfig(); g_showSounds_hWnd = NULL; return 0L; case WM_INITMENU: return 0L;
case WM_SIZE: ShowSounds_SizeWindow( hwnd, LOWORD( lParam ), HIWORD( lParam ) ); return 0L;
case WM_NOTIFY: switch ( ( ( LPNMHDR )lParam )->code ) { case LVN_COLUMNCLICK: NMLISTVIEW* pnmlv; pnmlv = ( NMLISTVIEW* )lParam; if ( g_showSounds_sortColumn == pnmlv->iSubItem ) { // user has clicked on same column - flip the sort
g_showSounds_sortDescending ^= 1; } else { // sort by new column
g_showSounds_sortColumn = pnmlv->iSubItem; } ShowSounds_SortItems(); return 0L;
case LVN_GETDISPINFO: NMLVDISPINFO* plvdi; plvdi = ( NMLVDISPINFO* )lParam; pSound = ( sound_t* )plvdi->item.lParam; switch ( plvdi->item.iSubItem ) { case ID_SS_NAME: plvdi->item.pszText = pSound->pName; return 0L;
case ID_SS_PREFIX: plvdi->item.pszText = pSound->pPrefix; return 0L; case ID_SS_FORMAT: plvdi->item.pszText = pSound->pFormat; return 0L;
case ID_SS_RATE: plvdi->item.pszText = pSound->rateBuff; return 0L;
case ID_SS_BITS: plvdi->item.pszText = pSound->bitsBuff; return 0L;
case ID_SS_CHANNELS: plvdi->item.pszText = pSound->channelsBuff; return 0L;
case ID_SS_SIZE: plvdi->item.pszText = pSound->dataSizeBuff; return 0L;
case ID_SS_STREAMED: plvdi->item.pszText = pSound->streamedBuff; return 0L;
case ID_SS_LOOPED: plvdi->item.pszText = pSound->loopedBuff; return 0L;
case ID_SS_LENGTH: plvdi->item.pszText = pSound->lengthBuff; return 0L;
default: break; } break; } break;
case WM_COMMAND: switch ( wID ) { case IDM_OPTIONS_SUMMARY: ShowSounds_Summary(); return 0L;
case IDM_OPTIONS_REFRESH: ShowSounds_Refresh(); return 0L;
case IDM_OPTIONS_EXPORT: ShowSounds_Export(); return 0L;
case IDM_OPTIONS_PLAYSOUND: ShowSounds_Play(); return 0L; } break; }
return ( DefWindowProc( hwnd, message, wParam, lParam ) ); }
//-----------------------------------------------------------------------------
// ShowSounds_Init
//
//-----------------------------------------------------------------------------
bool ShowSounds_Init() { // set up our window class
WNDCLASS wndclass;
memset( &wndclass, 0, sizeof( wndclass ) ); wndclass.style = 0; wndclass.lpfnWndProc = ShowSounds_WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = g_hInstance; wndclass.hIcon = g_hIcons[ICON_APPLICATION]; wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndclass.hbrBackground = g_hBackgroundBrush; wndclass.lpszMenuName = MAKEINTRESOURCE( MENU_SHOWSOUNDS ); wndclass.lpszClassName = "SHOWSOUNDSCLASS"; if ( !RegisterClass( &wndclass ) ) return false;
ShowSounds_LoadConfig();
return true; }
//-----------------------------------------------------------------------------
// ShowSounds_Open
//
//-----------------------------------------------------------------------------
void ShowSounds_Open() { RECT clientRect; HWND hWnd; int i;
if ( g_showSounds_hWnd ) { // only one instance
if ( IsIconic( g_showSounds_hWnd ) ) ShowWindow( g_showSounds_hWnd, SW_RESTORE ); SetForegroundWindow( g_showSounds_hWnd ); return; }
hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, "SHOWSOUNDSCLASS", "Sounds", WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_SIZEBOX|WS_MINIMIZEBOX|WS_MAXIMIZEBOX, 0, 0, 700, 400, g_hDlgMain, NULL, g_hInstance, NULL ); g_showSounds_hWnd = hWnd;
GetClientRect( g_showSounds_hWnd, &clientRect ); hWnd = CreateWindow( WC_LISTVIEW, "", WS_VISIBLE|WS_CHILD|LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SINGLESEL, 0, 0, clientRect.right-clientRect.left, clientRect.bottom-clientRect.top, g_showSounds_hWnd, ( HMENU )ID_SHOWSOUNDS_LISTVIEW, g_hInstance, NULL ); g_showSounds_hWndListView = hWnd;
// init list view columns
for ( i=0; i<sizeof( g_showSounds_Labels )/sizeof( g_showSounds_Labels[0] ); i++ ) { LVCOLUMN lvc; memset( &lvc, 0, sizeof( lvc ) );
lvc.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; lvc.iSubItem = 0; lvc.cx = g_showSounds_Labels[i].width; lvc.fmt = LVCFMT_LEFT; lvc.pszText = ( LPSTR )g_showSounds_Labels[i].name;
ListView_InsertColumn( g_showSounds_hWndListView, i, &lvc ); }
ListView_SetBkColor( g_showSounds_hWndListView, g_backgroundColor ); ListView_SetTextBkColor( g_showSounds_hWndListView, g_backgroundColor );
DWORD style = LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP; ListView_SetExtendedListViewStyleEx( g_showSounds_hWndListView, style, style );
// populate list view
for ( i=0; i<g_showSounds_numSounds; i++ ) ShowSounds_AddViewItem( &g_showSounds_pSounds[i] ); ShowSounds_SortItems();
if ( g_showSounds_windowRect.right && g_showSounds_windowRect.bottom ) MoveWindow( g_showSounds_hWnd, g_showSounds_windowRect.left, g_showSounds_windowRect.top, g_showSounds_windowRect.right-g_showSounds_windowRect.left, g_showSounds_windowRect.bottom-g_showSounds_windowRect.top, FALSE ); ShowWindow( g_showSounds_hWnd, SHOW_OPENWINDOW );
// get data from application
ShowSounds_Refresh(); }
//-----------------------------------------------------------------------------
// rc_SoundList
//
// Sent from application with sound list
//-----------------------------------------------------------------------------
int rc_SoundList( char* commandPtr ) { char* cmdToken; int numSounds; int soundList; int retAddr; int retVal; int errCode = -1; xrSound_t* pLocalList; int prefixLen; char *pStr;
// remove old entries
ShowSounds_Clear();
// get number of sounds
cmdToken = GetToken( &commandPtr ); if ( !cmdToken[0] ) goto cleanUp; sscanf( cmdToken, "%x", &numSounds );
// get sound list
cmdToken = GetToken( &commandPtr ); if ( !cmdToken[0] ) goto cleanUp; sscanf( cmdToken, "%x", &soundList );
// get retAddr
cmdToken = GetToken( &commandPtr ); if ( !cmdToken[0] ) goto cleanUp; sscanf( cmdToken, "%x", &retAddr );
pLocalList = new xrSound_t[numSounds]; memset( pLocalList, 0, numSounds*sizeof( xrSound_t ) );
g_showSounds_numSounds = numSounds; g_showSounds_pSounds = new sound_t[numSounds]; memset( g_showSounds_pSounds, 0, numSounds*sizeof( sound_t ) );
// get the caller's command list
DmGetMemory( ( void* )soundList, numSounds*sizeof( xrSound_t ), pLocalList, NULL );
// build out the resident list
for ( int i=0; i<numSounds; i++ ) { // swap the structure
pLocalList[i].rate = BigDWord( pLocalList[i].rate ); pLocalList[i].bits = BigDWord( pLocalList[i].bits ); pLocalList[i].channels = BigDWord( pLocalList[i].channels ); pLocalList[i].looped = BigDWord( pLocalList[i].looped ); pLocalList[i].dataSize = BigDWord( pLocalList[i].dataSize ); pLocalList[i].numSamples = BigDWord( pLocalList[i].numSamples ); pLocalList[i].streamed = BigDWord( pLocalList[i].streamed );
// strip the prefix
pStr = pLocalList[i].nameString; while ( *pStr ) { if ( __iscsym( *pStr ) ) { // first non-preifx character
break; } pStr++; } g_showSounds_pSounds[i].pName = strdup( pStr );
char prefixString[256]; prefixLen = pStr - pLocalList[i].nameString; memcpy( prefixString, pLocalList[i].nameString, prefixLen ); prefixString[prefixLen] = '\0'; g_showSounds_pSounds[i].pPrefix = strdup( prefixString );
// get the format name
g_showSounds_pSounds[i].pFormat = strdup( pLocalList[i].formatString );
g_showSounds_pSounds[i].rate = pLocalList[i].rate; g_showSounds_pSounds[i].bits = pLocalList[i].bits; g_showSounds_pSounds[i].channels = pLocalList[i].channels; g_showSounds_pSounds[i].dataSize = pLocalList[i].dataSize; g_showSounds_pSounds[i].numSamples = pLocalList[i].numSamples; g_showSounds_pSounds[i].streamed = pLocalList[i].streamed; g_showSounds_pSounds[i].looped = pLocalList[i].looped;
// determine duration
// must use sample count due to compression
if ( g_showSounds_pSounds[i].rate > 0 ) g_showSounds_pSounds[i].length = ( float )g_showSounds_pSounds[i].numSamples/( float )g_showSounds_pSounds[i].rate; else g_showSounds_pSounds[i].length = 0;
// add to list view
ShowSounds_AddViewItem( &g_showSounds_pSounds[i] ); }
// return the result
retVal = numSounds; int xboxRetVal = BigDWord( retVal ); DmSetMemory( ( void* )retAddr, sizeof( int ), &xboxRetVal, NULL );
DebugCommand( "0x%8.8x = SoundList( 0x%8.8x, 0x%8.8x )\n", retVal, numSounds, soundList );
delete [] pLocalList;
// update
ShowSounds_SortItems();
// success
errCode = 0;
cleanUp: return ( errCode ); }
|