diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/xbox/vxconsole/timestamp_log.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/xbox/vxconsole/timestamp_log.cpp')
| -rw-r--r-- | utils/xbox/vxconsole/timestamp_log.cpp | 623 |
1 files changed, 623 insertions, 0 deletions
diff --git a/utils/xbox/vxconsole/timestamp_log.cpp b/utils/xbox/vxconsole/timestamp_log.cpp new file mode 100644 index 0000000..1cc45ef --- /dev/null +++ b/utils/xbox/vxconsole/timestamp_log.cpp @@ -0,0 +1,623 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// TIMESTAMP_LOG.CPP +// +// TimeStamp Log Display. +//=====================================================================================// +#include "vxconsole.h" + +#define ID_TIMESTAMPLOG_LISTVIEW 100 + +// column id +#define ID_TSL_TIME 0 +#define ID_TSL_DELTATIME 1 +#define ID_TSL_MEMORY 2 +#define ID_TSL_DELTAMEMORY 3 +#define ID_TSL_MESSAGE 4 + +typedef struct +{ const CHAR* name; + int width; + int subItemIndex; + CHAR nameBuff[32]; +} label_t; + +struct timeStampLogNode_t +{ + int index; + float time; + float deltaTime; + int memory; + int deltaMemory; + char timeBuff[32]; + char deltaTimeBuff[32]; + char memoryBuff[32]; + char deltaMemoryBuff[32]; + char *pMessage; + timeStampLogNode_t *pNext; +}; + +HWND g_timeStampLog_hWnd; +HWND g_timeStampLog_hWndListView; +RECT g_timeStampLog_windowRect; +timeStampLogNode_t *g_timeStampLog_pNodes; +int g_timeStampLog_sortColumn; +int g_timeStampLog_sortDescending; + +label_t g_timeStampLog_Labels[] = +{ + {"Time", 100, ID_TSL_TIME}, + {"Delta Time", 100, ID_TSL_DELTATIME}, + {"Memory", 100, ID_TSL_MEMORY}, + {"Delta Memory", 100, ID_TSL_DELTAMEMORY}, + {"Message", 400, ID_TSL_MESSAGE}, +}; + +//----------------------------------------------------------------------------- +// TimeStampLog_CompareFunc +// +//----------------------------------------------------------------------------- +int CALLBACK TimeStampLog_CompareFunc( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ) +{ + timeStampLogNode_t* pNodeA = ( timeStampLogNode_t* )lParam1; + timeStampLogNode_t* pNodeB = ( timeStampLogNode_t* )lParam2; + + int sort = 0; + switch ( g_timeStampLog_sortColumn ) + { + case ID_TSL_TIME: + sort = ( int )( 1000.0f*pNodeA->time - 1000.0f*pNodeB->time ); + break; + + case ID_TSL_DELTATIME: + sort = ( int )( 1000.0f*pNodeA->deltaTime - 1000.0f*pNodeB->deltaTime ); + break; + + case ID_TSL_MEMORY: + sort = pNodeA->memory - pNodeB->memory; + break; + + case ID_TSL_DELTAMEMORY: + sort = pNodeA->deltaMemory - pNodeB->deltaMemory; + break; + + case ID_TSL_MESSAGE: + sort = stricmp( pNodeA->pMessage, pNodeB->pMessage ); + break; + } + + // flip the sort order + if ( g_timeStampLog_sortDescending ) + sort *= -1; + + return ( sort ); +} + +//----------------------------------------------------------------------------- +// TimeStampLog_SortItems +// +//----------------------------------------------------------------------------- +void TimeStampLog_SortItems() +{ + LVITEM lvitem; + timeStampLogNode_t *pNode; + int i; + + if ( !g_timeStampLog_hWnd ) + { + // only sort if window is visible + return; + } + + ListView_SortItems( g_timeStampLog_hWndListView, TimeStampLog_CompareFunc, 0 ); + + memset( &lvitem, 0, sizeof( lvitem ) ); + lvitem.mask = LVIF_PARAM; + + // get each item and reset its list index + int itemCount = ListView_GetItemCount( g_timeStampLog_hWndListView ); + for ( i=0; i<itemCount; i++ ) + { + lvitem.iItem = i; + ListView_GetItem( g_timeStampLog_hWndListView, &lvitem ); + + pNode = ( timeStampLogNode_t* )lvitem.lParam; + pNode->index = i; + } + + // update list view columns with sort key + for ( i=0; i<sizeof( g_timeStampLog_Labels )/sizeof( g_timeStampLog_Labels[0] ); i++ ) + { + char symbol; + LVCOLUMN lvc; + + if ( i == g_timeStampLog_sortColumn ) + symbol = g_timeStampLog_sortDescending ? '<' : '>'; + else + symbol = ' '; + sprintf( g_timeStampLog_Labels[i].nameBuff, "%s %c", g_timeStampLog_Labels[i].name, symbol ); + + memset( &lvc, 0, sizeof( lvc ) ); + lvc.mask = LVCF_TEXT; + lvc.pszText = ( LPSTR )g_timeStampLog_Labels[i].nameBuff; + + ListView_SetColumn( g_timeStampLog_hWndListView, i, &lvc ); + } +} + +//----------------------------------------------------------------------------- +// TimeStampLog_AddViewItem +// +//----------------------------------------------------------------------------- +void TimeStampLog_AddViewItem( timeStampLogNode_t* pNode ) +{ + LVITEM lvi; + + if ( !g_timeStampLog_hWnd ) + { + // only valid if log window is visible + return; + } + + // update the text callback buffers + sprintf( pNode->timeBuff, "%2.2d:%2.2d:%2.2d:%3.3d", ( int )pNode->time/3600, ( ( int )pNode->time/60 )%60, ( int )pNode->time%60, ( int )( 1000*( pNode->time-( int )pNode->time ) )%1000 ); + sprintf( pNode->deltaTimeBuff, "%.3f", pNode->deltaTime ); + sprintf( pNode->memoryBuff, "%.2f MB", pNode->memory/( 1024.0f*1024.0f ) ); + sprintf( pNode->deltaMemoryBuff, "%d", pNode->deltaMemory ); + + int itemCount = ListView_GetItemCount( g_timeStampLog_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 )pNode; + + // insert + pNode->index = ListView_InsertItem( g_timeStampLog_hWndListView, &lvi ); +} + +//----------------------------------------------------------------------------- +// TimeStampLog_AddItem +// +//----------------------------------------------------------------------------- +void TimeStampLog_AddItem( float time, float deltaTime, int memory, int deltaMemory, const char* pMessage ) +{ + timeStampLogNode_t* pNode; + + // create and init + pNode = new timeStampLogNode_t; + memset( pNode, 0, sizeof( timeStampLogNode_t ) ); + + pNode->time = time; + pNode->deltaTime = deltaTime; + pNode->memory = memory; + pNode->deltaMemory = deltaMemory; + pNode->pMessage = Sys_CopyString( pMessage ? pMessage : "" ); + + // link in + pNode->pNext = g_timeStampLog_pNodes; + g_timeStampLog_pNodes = pNode; + + TimeStampLog_AddViewItem( pNode ); +} + +//----------------------------------------------------------------------------- +// TimeStampLog_Clear +// +//----------------------------------------------------------------------------- +void TimeStampLog_Clear() +{ + timeStampLogNode_t* pNode; + timeStampLogNode_t* pNextNode; + + // delete all the list view entries + if ( g_timeStampLog_hWnd ) + ListView_DeleteAllItems( g_timeStampLog_hWndListView ); + + // delete nodes in chain + pNode = g_timeStampLog_pNodes; + while ( pNode ) + { + pNextNode = pNode->pNext; + + Sys_Free( pNode->pMessage ); + delete pNode; + + pNode = pNextNode; + } + g_timeStampLog_pNodes = NULL; +} + +//----------------------------------------------------------------------------- +// TimeStampLog_SaveConfig +// +//----------------------------------------------------------------------------- +void TimeStampLog_SaveConfig() +{ + char buff[256]; + + Sys_SetRegistryInteger( "timeStampLogSortColumn", g_timeStampLog_sortColumn ); + Sys_SetRegistryInteger( "timeStampLogSortDescending", g_timeStampLog_sortDescending ); + + WINDOWPLACEMENT wp; + memset( &wp, 0, sizeof( wp ) ); + wp.length = sizeof( WINDOWPLACEMENT ); + GetWindowPlacement( g_timeStampLog_hWnd, &wp ); + g_timeStampLog_windowRect = wp.rcNormalPosition; + + sprintf( buff, "%d %d %d %d", g_timeStampLog_windowRect.left, g_timeStampLog_windowRect.top, g_timeStampLog_windowRect.right, g_timeStampLog_windowRect.bottom ); + Sys_SetRegistryString( "timeStampLogWindowRect", buff ); +} + +//----------------------------------------------------------------------------- +// TimeStampLog_LoadConfig +// +//----------------------------------------------------------------------------- +void TimeStampLog_LoadConfig() +{ + int numArgs; + char buff[256]; + + Sys_GetRegistryInteger( "timeStampLogSortColumn", ID_TSL_TIME, g_timeStampLog_sortColumn ); + Sys_GetRegistryInteger( "timeStampLogSortDescending", false, g_timeStampLog_sortDescending ); + + Sys_GetRegistryString( "timeStampLogWindowRect", buff, "", sizeof( buff ) ); + numArgs = sscanf( buff, "%d %d %d %d", &g_timeStampLog_windowRect.left, &g_timeStampLog_windowRect.top, &g_timeStampLog_windowRect.right, &g_timeStampLog_windowRect.bottom ); + if ( numArgs != 4 || g_timeStampLog_windowRect.left < 0 || g_timeStampLog_windowRect.top < 0 || g_timeStampLog_windowRect.right < 0 || g_timeStampLog_windowRect.bottom < 0 ) + memset( &g_timeStampLog_windowRect, 0, sizeof( g_timeStampLog_windowRect ) ); +} + +//----------------------------------------------------------------------------- +// TimeStampLog_SizeWindow +// +//----------------------------------------------------------------------------- +void TimeStampLog_SizeWindow( HWND hwnd, int width, int height ) +{ + if ( width==0 || height==0 ) + { + RECT rcClient; + GetClientRect( hwnd, &rcClient ); + width = rcClient.right; + height = rcClient.bottom; + } + + // position the ListView + SetWindowPos( g_timeStampLog_hWndListView, NULL, 0, 0, width, height, SWP_NOZORDER ); +} + +//----------------------------------------------------------------------------- +// TimeStampLog_Export +// +//----------------------------------------------------------------------------- +void TimeStampLog_Export() +{ + OPENFILENAME ofn; + char logFilename[MAX_PATH]; + int retval; + FILE* fp; + int i; + int count; + + memset( &ofn, 0, sizeof( ofn ) ); + ofn.lStructSize = sizeof( ofn ); + ofn.hwndOwner = g_timeStampLog_hWnd; + ofn.lpstrFile = logFilename; + ofn.lpstrFile[0] = '\0'; + ofn.nMaxFile = sizeof( logFilename ); + ofn.lpstrFilter = "Excel CSV\0*.CSV\0All Files\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = "c:\\"; + ofn.Flags = OFN_PATHMUSTEXIST; + + // display the open dialog box + retval = GetOpenFileName( &ofn ); + if ( !retval ) + return; + + Sys_AddExtension( ".csv", logFilename, sizeof( logFilename ) ); + + fp = fopen( logFilename, "wt+" ); + if ( !fp ) + return; + + // labels + count = ARRAYSIZE( g_timeStampLog_Labels ); + for ( i=0; i<count; i++ ) + { + fprintf( fp, "\"%s\"", g_timeStampLog_Labels[i].name ); + if ( i != count-1 ) + fprintf( fp, "," ); + } + fprintf( fp, "\n" ); + + // build a list for easy reverse traversal + CUtlVector< timeStampLogNode_t* > nodeList; + timeStampLogNode_t *pNode; + pNode = g_timeStampLog_pNodes; + while ( pNode ) + { + nodeList.AddToTail( pNode ); + pNode = pNode->pNext; + } + + // dump to the log + for ( int i=nodeList.Count()-1; i>=0; i-- ) + { + pNode = nodeList[i]; + + fprintf( fp, "\"%s\"", pNode->timeBuff ); + fprintf( fp, ",\"%s\"", pNode->deltaTimeBuff ); + fprintf( fp, ",\"%s\"", pNode->memoryBuff ); + fprintf( fp, ",\"%s\"", pNode->deltaMemoryBuff ); + fprintf( fp, ",\"%s\"", pNode->pMessage ); + fprintf( fp, "\n" ); + } + + fclose( fp ); +} + +//----------------------------------------------------------------------------- +// TimeStampLog_WndProc +// +//----------------------------------------------------------------------------- +LRESULT CALLBACK TimeStampLog_WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) +{ + WORD wID = LOWORD( wParam ); + timeStampLogNode_t *pNode; + + switch ( message ) + { + case WM_CREATE: + return 0L; + + case WM_DESTROY: + TimeStampLog_SaveConfig(); + g_timeStampLog_hWnd = NULL; + return 0L; + + case WM_SIZE: + TimeStampLog_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_timeStampLog_sortColumn == pnmlv->iSubItem ) + { + // user has clicked on same column - flip the sort + g_timeStampLog_sortDescending ^= 1; + } + else + { + // sort by new column + g_timeStampLog_sortColumn = pnmlv->iSubItem; + } + TimeStampLog_SortItems(); + return 0L; + + case LVN_GETDISPINFO: + NMLVDISPINFO* plvdi; + plvdi = ( NMLVDISPINFO* )lParam; + pNode = ( timeStampLogNode_t * )plvdi->item.lParam; + switch ( plvdi->item.iSubItem ) + { + case ID_TSL_TIME: + plvdi->item.pszText = pNode->timeBuff; + return 0L; + + case ID_TSL_DELTATIME: + plvdi->item.pszText = pNode->deltaTimeBuff; + return 0L; + + case ID_TSL_MEMORY: + plvdi->item.pszText = pNode->memoryBuff; + return 0L; + + case ID_TSL_DELTAMEMORY: + plvdi->item.pszText = pNode->deltaMemoryBuff; + return 0L; + + case ID_TSL_MESSAGE: + plvdi->item.pszText = pNode->pMessage; + return 0L; + + default: + break; + } + break; + } + break; + + case WM_COMMAND: + switch ( wID ) + { + case IDM_OPTIONS_CLEAR: + TimeStampLog_Clear(); + return 0L; + + case IDM_OPTIONS_EXPORT: + TimeStampLog_Export(); + return 0L; + } + break; + } + + return ( DefWindowProc( hwnd, message, wParam, lParam ) ); +} + +//----------------------------------------------------------------------------- +// TimeStampLog_Init +// +//----------------------------------------------------------------------------- +bool TimeStampLog_Init() +{ + // set up our window class + WNDCLASS wndclass; + + memset( &wndclass, 0, sizeof( wndclass ) ); + wndclass.style = 0; + wndclass.lpfnWndProc = TimeStampLog_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_TIMESTAMPLOG ); + wndclass.lpszClassName = "TIMESTAMPLOGCLASS"; + if ( !RegisterClass( &wndclass ) ) + return false; + + TimeStampLog_LoadConfig(); + + return true; +} + +//----------------------------------------------------------------------------- +// TimeStampLog_Open +// +//----------------------------------------------------------------------------- +void TimeStampLog_Open() +{ + RECT clientRect; + HWND hWnd; + int i; + timeStampLogNode_t *pNode; + + if ( g_timeStampLog_hWnd ) + { + // only one file log instance + if ( IsIconic( g_timeStampLog_hWnd ) ) + ShowWindow( g_timeStampLog_hWnd, SW_RESTORE ); + SetForegroundWindow( g_timeStampLog_hWnd ); + return; + } + + hWnd = CreateWindowEx( + WS_EX_CLIENTEDGE, + "TIMESTAMPLOGCLASS", + "TimeStamp Log", + WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_SIZEBOX|WS_MINIMIZEBOX|WS_MAXIMIZEBOX, + 0, + 0, + 600, + 300, + g_hDlgMain, + NULL, + g_hInstance, + NULL ); + g_timeStampLog_hWnd = hWnd; + + GetClientRect( g_timeStampLog_hWnd, &clientRect ); + hWnd = CreateWindow( + WC_LISTVIEW, + "", + WS_VISIBLE|WS_CHILD|LVS_REPORT, + 0, + 0, + clientRect.right-clientRect.left, + clientRect.bottom-clientRect.top, + g_timeStampLog_hWnd, + ( HMENU )ID_TIMESTAMPLOG_LISTVIEW, + g_hInstance, + NULL ); + g_timeStampLog_hWndListView = hWnd; + + // init list view columns + for ( i=0; i<sizeof( g_timeStampLog_Labels )/sizeof( g_timeStampLog_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_timeStampLog_Labels[i].width; + lvc.fmt = LVCFMT_LEFT; + lvc.pszText = ( LPSTR )g_timeStampLog_Labels[i].name; + + ListView_InsertColumn( g_timeStampLog_hWndListView, i, &lvc ); + } + + ListView_SetBkColor( g_timeStampLog_hWndListView, g_backgroundColor ); + ListView_SetTextBkColor( g_timeStampLog_hWndListView, g_backgroundColor ); + + DWORD style = LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP; + ListView_SetExtendedListViewStyleEx( g_timeStampLog_hWndListView, style, style ); + + // populate list view + pNode = g_timeStampLog_pNodes; + while ( pNode ) + { + TimeStampLog_AddViewItem( pNode ); + pNode = pNode->pNext; + } + TimeStampLog_SortItems(); + + if ( g_timeStampLog_windowRect.right && g_timeStampLog_windowRect.bottom ) + MoveWindow( g_timeStampLog_hWnd, g_timeStampLog_windowRect.left, g_timeStampLog_windowRect.top, g_timeStampLog_windowRect.right-g_timeStampLog_windowRect.left, g_timeStampLog_windowRect.bottom-g_timeStampLog_windowRect.top, FALSE ); + ShowWindow( g_timeStampLog_hWnd, SHOW_OPENWINDOW ); +} + + +//----------------------------------------------------------------------------- +// rc_TimeStampLog +// +// Sent from application with time stamp log +//----------------------------------------------------------------------------- +int rc_TimeStampLog( char* commandPtr ) +{ + char *cmdToken; + int timeStampAddr; + int retAddr; + int retVal; + int errCode = -1; + xrTimeStamp_t timeStamp; + + // get data + cmdToken = GetToken( &commandPtr ); + if ( !cmdToken[0] ) + goto cleanUp; + sscanf( cmdToken, "%x", &timeStampAddr ); + + // get retAddr + cmdToken = GetToken( &commandPtr ); + if ( !cmdToken[0] ) + goto cleanUp; + sscanf( cmdToken, "%x", &retAddr ); + + // get the caller's data + DmGetMemory( ( void* )timeStampAddr, sizeof( xrTimeStamp_t ), &timeStamp, NULL ); + + // swap the structure + BigFloat( &timeStamp.time, &timeStamp.time ); + BigFloat( &timeStamp.deltaTime, &timeStamp.deltaTime ); + timeStamp.memory = BigDWord( timeStamp.memory ); + timeStamp.deltaMemory = BigDWord( timeStamp.deltaMemory ); + + // add to log + TimeStampLog_AddItem( timeStamp.time, timeStamp.deltaTime, timeStamp.memory, timeStamp.deltaMemory, timeStamp.messageString ); + TimeStampLog_SortItems(); + + // return the result + retVal = 0; + int xboxRetVal = BigDWord( retVal ); + DmSetMemory( ( void* )retAddr, sizeof( int ), &xboxRetVal, NULL ); + + DebugCommand( "0x%8.8x = TimeStampLog( 0x%8.8x )\n", retVal, timeStampAddr ); + + // success + errCode = 0; + +cleanUp: + return ( errCode ); +} |