//----------------------------------------------------------------------------- // Output string to listening console. Queues output for slave thread. // Needs to be lightweight. //----------------------------------------------------------------------------- void CXboxConsole::DebugString( unsigned int color, const char* pFormat, ... ) { if ( XBX_NoXBDM() ) return; va_list args; char szStringBuffer[XBX_MAX_MESSAGE]; int length; // resolve string va_start( args, pFormat ); length = _vsnprintf( szStringBuffer, sizeof( szStringBuffer ), pFormat, args ); if ( length == -1 ) { szStringBuffer[sizeof( szStringBuffer ) - 1] = '\0'; } va_end( args ); if ( !g_xbx_bDoSyncOutput ) { // queue string for delayed output DebugString_t debugString; debugString.color = color; debugString.pString = strdup( szStringBuffer ); g_xbx_DebugStringQueue.PushItem( debugString ); } else { bool bRemoteValid = g_xbx_bUseVXConsoleOutput && XBX_IsConsoleConnected(); OutputStringToDevice( color, szStringBuffer, bRemoteValid ); } }
//----------------------------------------------------------------------------- // Handle delayed VXConsole transactions // //----------------------------------------------------------------------------- static unsigned _DebugThreadFunc( void *pParam ) { while ( 1 ) { Sleep( 10 ); if ( !g_xbx_DebugStringQueue.Count() && !g_xbx_numProfileCounters && !g_xbx_freeMemory ) { continue; } if ( g_xbx_numProfileCounters ) { // build and send asynchronously char dbgCommand[XBX_MAX_RCMDLENGTH]; _snprintf( dbgCommand, sizeof( dbgCommand ), "SetProfileData() %s 0x%8.8x", g_xbx_profileName, g_xbx_profileCounters ); XBX_SendRemoteCommand( dbgCommand, true ); // mark as sent g_xbx_numProfileCounters = 0; } if ( g_xbx_freeMemory ) { // build and send asynchronously char dbgCommand[XBX_MAX_RCMDLENGTH]; _snprintf( dbgCommand, sizeof( dbgCommand ), "FreeMemory() 0x%8.8x", g_xbx_freeMemory ); XBX_SendRemoteCommand( dbgCommand, true ); // mark as sent g_xbx_freeMemory = 0; } bool bRemoteValid = g_xbx_bUseVXConsoleOutput && XBX_IsConsoleConnected(); while ( 1 ) { DebugString_t debugString; if ( !g_xbx_DebugStringQueue.PopItem( &debugString ) ) { break; } OutputStringToDevice( debugString.color, debugString.pString, bRemoteValid ); free( debugString.pString ); } } return 0; }
//----------------------------------------------------------------------------- // globals //----------------------------------------------------------------------------- SpewRetval_t DefaultSpewFunc( SpewType_t type, const tchar *pMsg ) { #ifdef _X360 if ( XBX_IsConsoleConnected() ) { // send to console XBX_DebugString( XMAKECOLOR( 0,0,0 ), pMsg ); } else #endif { _tprintf( _T("%s"), pMsg ); #ifdef _WIN32 Plat_DebugString( pMsg ); #endif } if ( type == SPEW_ASSERT ) return SPEW_DEBUGGER; else if ( type == SPEW_ERROR ) return SPEW_ABORT; else return SPEW_CONTINUE; }