#include "stdafx.h" #include BOOL TraceClosed = FALSE; class CTraceLog { std::vector m_Modules; CriticalSection m_CS; public: CTraceLog() { } ~CTraceLog() { CloseTrace(); } CTraceModule * AddTraceModule(CTraceModule * TraceModule); CTraceModule * RemoveTraceModule(CTraceModule * TraceModule); void CloseTrace(void); void WriteTrace(TraceType Type, LPCTSTR Message); void WriteTraceF(TraceType Type, LPCTSTR strFormat, va_list args); }; CTraceModule * CTraceLog::AddTraceModule(CTraceModule * TraceModule) { CGuard Guard(m_CS); for (int i = 0; i < (int)m_Modules.size(); i++) { if (m_Modules[i] == TraceModule) { return TraceModule; } } m_Modules.push_back(TraceModule); return TraceModule; } CTraceModule * CTraceLog::RemoveTraceModule(CTraceModule * TraceModule) { CGuard Guard(m_CS); for (std::vector::iterator itr = m_Modules.begin(); itr != m_Modules.end(); itr++) { if ((*itr) == TraceModule) { m_Modules.erase(itr); return TraceModule; } } return NULL; } void CTraceLog::CloseTrace(void) { CGuard Guard(m_CS); for (int i = 0; i < (int)m_Modules.size(); i++) { if (m_Modules[i]) delete m_Modules[i]; } m_Modules.clear(); } void CTraceLog::WriteTraceF(TraceType Type, LPCTSTR strFormat, va_list args) { const int nMaxSize = 32 * 1024; TCHAR pBuffer[nMaxSize]; _vsntprintf(pBuffer, nMaxSize, strFormat, args); pBuffer[nMaxSize - 1] = 0; WriteTrace(Type, pBuffer); } void CTraceLog::WriteTrace(TraceType Type, LPCTSTR Message) { CGuard Guard(m_CS); if (Type != TraceNone) { bool WriteToLog = false; for (int i = 0; i < (int)m_Modules.size(); i++) { if ((m_Modules[i]->GetTraceLevel() & Type) != 0) { WriteToLog = true; break; } } if (!WriteToLog) { return; } } if ((Type & TraceNoHeader) == 0) { TCHAR pBuffer[300]; int nPos = 0; SYSTEMTIME sysTime; ::GetLocalTime(&sysTime); nPos = _stprintf(pBuffer, _T("%04d/%02d/%02d %02d:%02d:%02d.%03d %05d: "), sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds, ::GetCurrentThreadId() ); // show the debug level if (Type == TraceNone) { nPos += _stprintf(pBuffer + nPos, _T("%s"), _T("None : ")); } else if ((Type & TraceError) != 0) { nPos += _stprintf(pBuffer + nPos, _T("%s"), _T("Error : ")); } else if ((Type & TraceSettings) != 0) { nPos += _stprintf(pBuffer + nPos, _T("%s"), _T("Setting: ")); } else if ((Type & TraceGfxPlugin) != 0) { nPos += _stprintf(pBuffer + nPos, _T("%s"), _T("Gfx : ")); } else if ((Type & TraceDebug) != 0) { nPos += _stprintf(pBuffer + nPos, _T("%s"), _T("Debug : ")); } else if ((Type & TraceRecompiler) != 0) { nPos += _stprintf(pBuffer + nPos, _T("%s"), _T("Recomp : ")); } else if ((Type & TraceRSP) != 0) { nPos += _stprintf(pBuffer + nPos, _T("%s"), _T("RSP : ")); } else if ((Type & TraceTLB) != 0) { nPos += _stprintf(pBuffer + nPos, _T("%s"), _T("TLB : ")); } else if ((Type & TraceValidate) != 0) { nPos += _stprintf(pBuffer + nPos, _T("%s"), _T("Valid : ")); } else if ((Type & TraceAudio) != 0) { nPos += _stprintf(pBuffer + nPos, _T("%s"), _T("Audio : ")); } else { nPos += _stprintf(pBuffer + nPos, _T("%s"), _T("Unknown: ")); } for (int i = 0; i < (int)m_Modules.size(); i++) { if ((m_Modules[i]->GetTraceLevel() & Type) != 0) { m_Modules[i]->Write(pBuffer, false); } } } for (int i = 0; i < (int)m_Modules.size(); i++) { if ((m_Modules[i]->GetTraceLevel() & Type) != 0) { m_Modules[i]->Write(Message, true); } } } CTraceLog & GetTraceObjet(void) { static CTraceLog TraceLog; return TraceLog; } void WriteTrace(TraceType Type, LPCTSTR Message) { if (TraceClosed) { return; } GetTraceObjet().WriteTrace(Type, Message); } void WriteTraceF(TraceType Type, LPCTSTR strFormat, ...) { if (TraceClosed) { return; } va_list args; va_start(args, strFormat); GetTraceObjet().WriteTraceF(Type, strFormat, args); va_end(args); } CTraceModule * AddTraceModule(CTraceModule * TraceModule) { if (TraceClosed) { return NULL; } GetTraceObjet().AddTraceModule(TraceModule); return TraceModule; } CTraceModule * RemoveTraceModule(CTraceModule * TraceModule) { return GetTraceObjet().RemoveTraceModule(TraceModule); } void CloseTrace(void) { TraceClosed = true; GetTraceObjet().CloseTrace(); } CTraceFileLog::CTraceFileLog(LPCTSTR FileName, bool FlushFile) : m_FlushFile(FlushFile) { m_hLogFile.SetFlush(false); m_hLogFile.SetTruncateFile(true); m_hLogFile.SetMaxFileSize(5 * MB); m_hLogFile.Open(FileName, Log_Append); } CTraceFileLog::CTraceFileLog(LPCTSTR FileName, bool FlushFile, LOG_OPEN_MODE eMode, size_t dwMaxFileSize) : m_FlushFile(FlushFile) { enum { MB = 1024 * 1024 }; m_hLogFile.SetFlush(false); m_hLogFile.SetTruncateFile(true); if (dwMaxFileSize < 3 || dwMaxFileSize > 2047) { /* Clamp file size to 5 MB if it exceeds 2047 or falls short of 3. */ dwMaxFileSize = 5; } m_hLogFile.SetMaxFileSize(dwMaxFileSize * MB); m_hLogFile.Open(FileName, eMode); } CTraceFileLog::~CTraceFileLog() { TraceClosed = true; } void CTraceFileLog::Write(LPCTSTR Message, bool EndOfLine) { if (!m_hLogFile.IsOpen()) { return; } CGuard Section(m_CriticalSection); m_hLogFile.Log(Message); if (EndOfLine) { m_hLogFile.Log(_T("\r\n")); if (m_FlushFile) { m_hLogFile.Flush(); } } } void CTraceFileLog::SetFlushFile(bool bFlushFile) { m_FlushFile = bFlushFile; } void CDebugTraceLog::Write(const char * Message, bool EndOfLine) { OutputDebugString(Message); if (EndOfLine) { OutputDebugString("\n"); } }