/*========================================================================== * * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved. * * File: newdpf.c * Content: new debug printf *@@BEGIN_MSINTERNAL * History: * Date By Reason * ==== == ====== * 10-oct-95 jeffno initial implementation *@@END_MSINTERNAL * ***************************************************************************/ #if defined(DEBUG) || defined(DBG) #ifdef IS_16 #define OUTPUTDEBUGSTRING OutputDebugString #define GETPROFILESTRING GetProfileString #define GETPROFILEINT GetProfileInt #define WSPRINTF wsprintf #define WVSPRINTF wvsprintf #define LSTRLEN lstrlen #else #define OUTPUTDEBUGSTRING OutputDebugStringA #define GETPROFILESTRING GetProfileStringA #define GETPROFILEINT GetProfileIntA #define WSPRINTF wsprintfA #define WVSPRINTF wvsprintfA #define LSTRLEN lstrlenA #endif #include "dpf.h" #undef DEBUG_TOPIC #define DEBUG_TOPIC(flag,name) {#flag,name,TRUE}, static struct { char cFlag[4]; char cName[64]; BOOL bOn; } DebugTopics[] = { {"","Filler",FALSE}, {"A","API Usage",TRUE}, #include "DBGTOPIC.H" {"","End",FALSE} }; #ifndef PROF_SECT #define PROF_SECT "Direct3D" #endif #ifndef PROF_SECT_D3D #define PROF_SECT_D3D "Direct3D" #endif #ifndef START_STR_D3D #define START_STR_D3D "Direct3D8: " #endif #define END_STR "\r\n" #undef DPF_MODULE_NAME #define DPF_MODULE_NAME "Direct3D8: " static DWORD bDetailOn = 1; static BOOL bInited=FALSE; static BOOL bAllowMisc=TRUE; static bBreakOnAsserts=FALSE; static bPrintLineNumbers=FALSE; static bPrintFileNames=FALSE; static bPrintExecutableName=FALSE; static bPrintTID=FALSE; static bPrintPID=FALSE; static bIndentOnMessageLevel=FALSE; static bPrintTopicsAndLevels=FALSE; static bPrintModuleName=TRUE; static bPrintFunctionName=FALSE; static bRespectColumns=FALSE; static bPrintAPIStats=FALSE; static bPrintAllTopics=TRUE; static bAdvancedDPFs=FALSE; static DWORD dwFileLineTID=0; static char cFile[100]; static char cFnName[100]; static DWORD dwLineNo; static bMute=FALSE; // Debug level for D3D LONG lD3dDebugLevel = 0; DPF_PROC_STATS ProcStats[MAX_PROC_ORDINAL]; #ifdef cplusplus extern "C" { #endif void mystrncpy(char * to,char * from,int n) { for(;n;n--) *(to++)=*(from++); } char * mystrrchr(char * in,char c) { char * last=0; while (*in) { if (*in == c) last = in; in++; } return last; } char Junk[]="DPF_MODNAME undef'd"; char * DPF_MODNAME = Junk; int DebugSetFileLineEtc(LPSTR szFile, DWORD dwLineNumber, LPSTR szFnName) { if (!(bPrintFileNames||bPrintLineNumbers||bPrintFunctionName)) { return 1; } #ifdef WIN32 dwFileLineTID = GetCurrentThreadId(); #endif mystrncpy (cFile,szFile,sizeof(cFile)); mystrncpy (cFnName,szFnName,sizeof(cFnName)); dwLineNo = dwLineNumber; return 1; } static void dumpStr( LPSTR str ) { /* * Have to warm the string, since OutputDebugString is buried * deep enough that it won't page the string in before reading it. */ int i=0; if (str) while(str[i]) i++; OUTPUTDEBUGSTRING( str ); OUTPUTDEBUGSTRING("\n"); } void DebugPrintfInit(void) { signed int lDebugLevel; int i; char cTopics[100]; lD3dDebugLevel = GetProfileInt( PROF_SECT_D3D, "debug", 0 ); bDetailOn=1; for (i=0;i: Indent on message detail levels"); dumpStr(" &: Print the topic and detail level of each message"); dumpStr(" =: Print function name"); dumpStr(" +: Print all topics, including topic-less"); dumpStr(" / or -: do not allow topic-less messages"); dumpStr(" @ or $: Print source filename and line number of DPF"); dumpStr("Topics for this module are:"); for(i=0;strcmp(DebugTopics[i].cName,"End");i++) { OUTPUTDEBUGSTRING(" "); OUTPUTDEBUGSTRING(DebugTopics[i].cFlag); OUTPUTDEBUGSTRING(": "); dumpStr(DebugTopics[i].cName); } dumpStr("Tip: Use 0-3A to get debug info about API calls"); } } bInited=TRUE; } /* * * The full output can be: * Module:(Executable,TxNNNN,PxNN):FunctionName:"file.c",#nnn(AAnn) Messagemessagemessage * or, if indentation turned on: * Module:(Executable,TxNNNN,PxNN):FunctionName:"file.c",#nnn(AAnn) Messagemessagemessage */ int DebugPrintf(DWORD dwDetail, ...) { #define MSGBUFFERSIZE 1000 BOOL bAllowed=FALSE; BOOL bMiscMessage=TRUE; char cMsg[MSGBUFFERSIZE]; char cTopics[20]; DWORD_PTR arg; LPSTR szFormat; int i; #ifdef WIN95 char szTemp[MSGBUFFERSIZE]; char *psz = NULL; #endif va_list ap; if (!bInited) DebugPrintfInit(); //error checking: if (dwDetail >= 10) return 1; if ( (bDetailOn & (1<0 && arg < LAST_TOPIC) { bMiscMessage=FALSE; if (DebugTopics[arg].bOn) bAllowed = TRUE; } } //if this message has no topics, then it's a misc message. //we turn them on only if allowed (i.e. "-" is not in the enable string). //And level zero messages are always allowed if (bMiscMessage) { if (bAllowMisc || dwDetail == 0) bAllowed=TRUE; } else { //topic-ed message is only allowed if the advanced DPF line is set in [DirectX] if (!bAdvancedDPFs) bAllowed=FALSE; } //Advanced DPFs have the option ("+") to print every topic if (bAdvancedDPFs) { if ( bPrintAllTopics ) bAllowed=TRUE; } if (!bAllowed) return FALSE; szFormat = (LPSTR) arg; cMsg[0]=0; /* * Add the module name first */ if (bPrintModuleName) { WSPRINTF( cMsg+strlen(cMsg),DPF_MODULE_NAME); } if (dwDetail==0) { WSPRINTF( cMsg+strlen(cMsg),"(ERROR) :" ); } if (dwDetail==1) { WSPRINTF( cMsg+strlen(cMsg),"(WARN) :" ); } if (dwDetail==2) { WSPRINTF( cMsg+strlen(cMsg),"(INFO) :" ); } if (bPrintExecutableName || bPrintTID || bPrintPID) WSPRINTF( cMsg+strlen(cMsg),"("); #ifdef WIN32 #if 0 /* * deleted due to RIP in GetModuleFilename on debug windows when win16 lock held */ if (bPrintExecutableName) { GetModuleFileName(NULL,str,256); if (mystrrchr(str,'\\')) WSPRINTF(cMsg+strlen(cMsg),"%12s",mystrrchr(str,'\\')+1); } #endif if (bPrintPID) { if (bPrintExecutableName) strcat(cMsg,","); WSPRINTF( cMsg+strlen(cMsg),"Px%02x",GetCurrentProcessId()); } if (bPrintTID) { if (bPrintExecutableName || bPrintPID) strcat(cMsg,","); WSPRINTF( cMsg+strlen(cMsg),"Tx%04x",GetCurrentThreadId()); } if (bPrintExecutableName || bPrintTID || bPrintPID) WSPRINTF( cMsg+strlen(cMsg),"):"); #endif if (bPrintFunctionName) { WSPRINTF( cMsg+strlen(cMsg),cFnName); } if (bPrintFileNames || bPrintLineNumbers) { if (mystrrchr(cFile,'\\')) WSPRINTF( cMsg+strlen(cMsg),":%12s",mystrrchr(cFile,'\\')+1 ); else WSPRINTF( cMsg+strlen(cMsg),":%12s",cFile); WSPRINTF( cMsg+strlen(cMsg),"@%d",dwLineNo); } if (bPrintTopicsAndLevels) { WSPRINTF( cMsg+strlen(cMsg),"(%3s)",cTopics); } if (cMsg[strlen(cMsg)-1] != ':') WSPRINTF( cMsg+strlen(cMsg),":"); if (bIndentOnMessageLevel) { for(i=0;(DWORD)i%s",pIface,pFunctionName); } void DebugSetTopicsAndLevels(char * cTopics) { int i; int j; bAllowMisc=TRUE; bBreakOnAsserts=FALSE; bPrintLineNumbers=FALSE; bPrintFileNames=FALSE; bPrintExecutableName=FALSE; bPrintTID=FALSE; bPrintPID=FALSE; bIndentOnMessageLevel=FALSE; bPrintTopicsAndLevels=FALSE; bPrintFunctionName=FALSE; bPrintAPIStats=FALSE; bPrintAllTopics=FALSE; bDetailOn=1; /* always print detail level 0*/ for (i=0;(DWORD)i': bIndentOnMessageLevel=TRUE; break; case '&': bPrintTopicsAndLevels=TRUE; break; case '=': bPrintFunctionName=TRUE; break; case '%': bPrintAPIStats=TRUE; break; case '+': bPrintAllTopics=TRUE; break; default: if (cTopics[i]>='0' && cTopics[i]<='9') { if (cTopics[i+1]=='-') { if (cTopics[i+2]>='0' && cTopics[i+2]<='9') { for(j=cTopics[i]-'0';j<=cTopics[i+2]-'0';j++) bDetailOn |= 1<= lvl ) { allow = TRUE; } if( allow ) { wsprintf( (LPSTR) str, START_STR_D3D ); wsprintf( (LPSTR) str+lstrlen( str ), msgType ); #ifdef WIN95 { char szTmp[512]; char *psz = szTmp; strncpy(szTmp, szFormat, 512); // %p does not work on Windows95. // We look for each "%p" and substitute 'x' for 'p' // WARNING: This code does not handle escape sequences using %p. // Extra code must be added to deal with that case // if necessary while (psz = strstr(psz, "%p")) *(psz+1) = 'x'; wvsprintf( str+lstrlen( str ), szTmp, ap); } #else wvsprintf( str+lstrlen( str ), szFormat, ap); //(LPVOID)(&szFormat+1) ); #endif // WIN95 lstrcat( (LPSTR) str, END_STR ); dumpStr( str ); } } /* D3Dprintf */ void cdecl D3DInfoPrintf( UINT lvl, LPSTR szFormat, ...) { va_list ap; va_start(ap, szFormat); D3Dprintf(lvl, "(INFO) :", szFormat, ap); va_end(ap); } void cdecl D3DWarnPrintf( UINT lvl, LPSTR szFormat, ...) { va_list ap; va_start(ap,szFormat); D3Dprintf(lvl, "(WARN) :", szFormat, ap); va_end(ap); } void cdecl D3DErrorPrintf( LPSTR szFormat, ...) { va_list ap; va_start(ap,szFormat); D3Dprintf(0, "(ERROR) :", szFormat, ap); va_end(ap); } #ifdef cplusplus } #endif #else // !debug void DebugSetMute(BOOL bMuteFlag) { } #endif //defined debug