mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	convert tabs to spaces
This commit is contained in:
		
							parent
							
								
									4860480c36
								
							
						
					
					
						commit
						c9b5b89e21
					
				
					 47 changed files with 4913 additions and 4913 deletions
				
			
		|  | @ -1,18 +1,18 @@ | |||
| set(SRCS	src/break_points.cpp | ||||
| 			src/console_listener.cpp | ||||
| 			src/extended_trace.cpp | ||||
| 			src/file_search.cpp | ||||
| 			src/file_util.cpp | ||||
| 			src/hash.cpp | ||||
| 			src/log_manager.cpp | ||||
| 			src/math_util.cpp | ||||
| 			src/mem_arena.cpp | ||||
| 			src/memory_util.cpp | ||||
| 			src/misc.cpp | ||||
| 			src/msg_handler.cpp | ||||
| 			src/string_util.cpp | ||||
| 			src/thread.cpp | ||||
| 			src/timer.cpp | ||||
| 			src/version.cpp) | ||||
| set(SRCS    src/break_points.cpp | ||||
|             src/console_listener.cpp | ||||
|             src/extended_trace.cpp | ||||
|             src/file_search.cpp | ||||
|             src/file_util.cpp | ||||
|             src/hash.cpp | ||||
|             src/log_manager.cpp | ||||
|             src/math_util.cpp | ||||
|             src/mem_arena.cpp | ||||
|             src/memory_util.cpp | ||||
|             src/misc.cpp | ||||
|             src/msg_handler.cpp | ||||
|             src/string_util.cpp | ||||
|             src/thread.cpp | ||||
|             src/timer.cpp | ||||
|             src/version.cpp) | ||||
| 
 | ||||
| add_library(common STATIC ${SRCS}) | ||||
|  |  | |||
|  | @ -25,42 +25,42 @@ namespace Common | |||
| { | ||||
| 
 | ||||
| inline void AtomicAdd(volatile u32& target, u32 value) { | ||||
| 	__sync_add_and_fetch(&target, value); | ||||
|     __sync_add_and_fetch(&target, value); | ||||
| } | ||||
| 
 | ||||
| inline void AtomicAnd(volatile u32& target, u32 value) { | ||||
| 	__sync_and_and_fetch(&target, value); | ||||
|     __sync_and_and_fetch(&target, value); | ||||
| } | ||||
| 
 | ||||
| inline void AtomicDecrement(volatile u32& target) { | ||||
| 	__sync_add_and_fetch(&target, -1); | ||||
|     __sync_add_and_fetch(&target, -1); | ||||
| } | ||||
| 
 | ||||
| inline void AtomicIncrement(volatile u32& target) { | ||||
| 	__sync_add_and_fetch(&target, 1); | ||||
|     __sync_add_and_fetch(&target, 1); | ||||
| } | ||||
| 
 | ||||
| inline u32 AtomicLoad(volatile u32& src) { | ||||
| 	return src; // 32-bit reads are always atomic.
 | ||||
|     return src; // 32-bit reads are always atomic.
 | ||||
| } | ||||
| inline u32 AtomicLoadAcquire(volatile u32& src) { | ||||
| 	//keep the compiler from caching any memory references
 | ||||
| 	u32 result = src; // 32-bit reads are always atomic.
 | ||||
| 	//__sync_synchronize(); // TODO: May not be necessary.
 | ||||
| 	// Compiler instruction only. x86 loads always have acquire semantics.
 | ||||
| 	__asm__ __volatile__ ( "":::"memory" ); | ||||
| 	return result; | ||||
|     //keep the compiler from caching any memory references
 | ||||
|     u32 result = src; // 32-bit reads are always atomic.
 | ||||
|     //__sync_synchronize(); // TODO: May not be necessary.
 | ||||
|     // Compiler instruction only. x86 loads always have acquire semantics.
 | ||||
|     __asm__ __volatile__ ( "":::"memory" ); | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| inline void AtomicOr(volatile u32& target, u32 value) { | ||||
| 	__sync_or_and_fetch(&target, value); | ||||
|     __sync_or_and_fetch(&target, value); | ||||
| } | ||||
| 
 | ||||
| inline void AtomicStore(volatile u32& dest, u32 value) { | ||||
| 	dest = value; // 32-bit writes are always atomic.
 | ||||
|     dest = value; // 32-bit writes are always atomic.
 | ||||
| } | ||||
| inline void AtomicStoreRelease(volatile u32& dest, u32 value) { | ||||
| 	__sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics.
 | ||||
|     __sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics.
 | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -31,40 +31,40 @@ namespace Common | |||
| { | ||||
| 
 | ||||
| inline void AtomicAdd(volatile u32& target, u32 value) { | ||||
| 	InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value); | ||||
|     InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value); | ||||
| } | ||||
| 
 | ||||
| inline void AtomicAnd(volatile u32& target, u32 value) { | ||||
| 	_InterlockedAnd((volatile LONG*)&target, (LONG)value); | ||||
|     _InterlockedAnd((volatile LONG*)&target, (LONG)value); | ||||
| } | ||||
| 
 | ||||
| inline void AtomicIncrement(volatile u32& target) { | ||||
| 	InterlockedIncrement((volatile LONG*)&target); | ||||
|     InterlockedIncrement((volatile LONG*)&target); | ||||
| } | ||||
| 
 | ||||
| inline void AtomicDecrement(volatile u32& target) { | ||||
| 	InterlockedDecrement((volatile LONG*)&target); | ||||
|     InterlockedDecrement((volatile LONG*)&target); | ||||
| } | ||||
| 
 | ||||
| inline u32 AtomicLoad(volatile u32& src) { | ||||
| 	return src; // 32-bit reads are always atomic.
 | ||||
|     return src; // 32-bit reads are always atomic.
 | ||||
| } | ||||
| inline u32 AtomicLoadAcquire(volatile u32& src) { | ||||
| 	u32 result = src; // 32-bit reads are always atomic.
 | ||||
| 	_ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics.
 | ||||
| 	return result; | ||||
|     u32 result = src; // 32-bit reads are always atomic.
 | ||||
|     _ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics.
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| inline void AtomicOr(volatile u32& target, u32 value) { | ||||
| 	_InterlockedOr((volatile LONG*)&target, (LONG)value); | ||||
|     _InterlockedOr((volatile LONG*)&target, (LONG)value); | ||||
| } | ||||
| 
 | ||||
| inline void AtomicStore(volatile u32& dest, u32 value) { | ||||
| 	dest = value; // 32-bit writes are always atomic.
 | ||||
|     dest = value; // 32-bit writes are always atomic.
 | ||||
| } | ||||
| inline void AtomicStoreRelease(volatile u32& dest, u32 value) { | ||||
| 	_WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics.
 | ||||
| 	dest = value; // 32-bit writes are always atomic.
 | ||||
|     _WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics.
 | ||||
|     dest = value; // 32-bit writes are always atomic.
 | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -11,193 +11,193 @@ | |||
| 
 | ||||
| bool BreakPoints::IsAddressBreakPoint(u32 _iAddress) | ||||
| { | ||||
| 	for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | ||||
| 		if (i->iAddress == _iAddress) | ||||
| 			return true; | ||||
| 	return false; | ||||
|     for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | ||||
|         if (i->iAddress == _iAddress) | ||||
|             return true; | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| bool BreakPoints::IsTempBreakPoint(u32 _iAddress) | ||||
| { | ||||
| 	for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | ||||
| 		if (i->iAddress == _iAddress && i->bTemporary) | ||||
| 			return true; | ||||
| 	return false; | ||||
|     for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | ||||
|         if (i->iAddress == _iAddress && i->bTemporary) | ||||
|             return true; | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const | ||||
| { | ||||
| 	TBreakPointsStr bps; | ||||
| 	for (TBreakPoints::const_iterator i = m_BreakPoints.begin(); | ||||
| 		i != m_BreakPoints.end(); ++i) | ||||
| 	{ | ||||
| 		if (!i->bTemporary) | ||||
| 		{ | ||||
| 			std::stringstream bp; | ||||
| 			bp << std::hex << i->iAddress << " " << (i->bOn ? "n" : ""); | ||||
| 			bps.push_back(bp.str()); | ||||
| 		} | ||||
| 	} | ||||
|     TBreakPointsStr bps; | ||||
|     for (TBreakPoints::const_iterator i = m_BreakPoints.begin(); | ||||
|         i != m_BreakPoints.end(); ++i) | ||||
|     { | ||||
|         if (!i->bTemporary) | ||||
|         { | ||||
|             std::stringstream bp; | ||||
|             bp << std::hex << i->iAddress << " " << (i->bOn ? "n" : ""); | ||||
|             bps.push_back(bp.str()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	return bps; | ||||
|     return bps; | ||||
| } | ||||
| 
 | ||||
| void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) | ||||
| { | ||||
| 	for (TBreakPointsStr::const_iterator i = bps.begin(); i != bps.end(); ++i) | ||||
| 	{ | ||||
| 		TBreakPoint bp; | ||||
| 		std::stringstream bpstr; | ||||
| 		bpstr << std::hex << *i; | ||||
| 		bpstr >> bp.iAddress; | ||||
| 		bp.bOn = i->find("n") != i->npos; | ||||
| 		bp.bTemporary = false; | ||||
| 		Add(bp); | ||||
| 	} | ||||
|     for (TBreakPointsStr::const_iterator i = bps.begin(); i != bps.end(); ++i) | ||||
|     { | ||||
|         TBreakPoint bp; | ||||
|         std::stringstream bpstr; | ||||
|         bpstr << std::hex << *i; | ||||
|         bpstr >> bp.iAddress; | ||||
|         bp.bOn = i->find("n") != i->npos; | ||||
|         bp.bTemporary = false; | ||||
|         Add(bp); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void BreakPoints::Add(const TBreakPoint& bp) | ||||
| { | ||||
| 	if (!IsAddressBreakPoint(bp.iAddress)) | ||||
| 	{ | ||||
| 		m_BreakPoints.push_back(bp); | ||||
| 		//if (jit)
 | ||||
| 		//	jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 | ||||
| 	} | ||||
|     if (!IsAddressBreakPoint(bp.iAddress)) | ||||
|     { | ||||
|         m_BreakPoints.push_back(bp); | ||||
|         //if (jit)
 | ||||
|         //    jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void BreakPoints::Add(u32 em_address, bool temp) | ||||
| { | ||||
| 	if (!IsAddressBreakPoint(em_address)) // only add new addresses
 | ||||
| 	{ | ||||
| 		TBreakPoint pt; // breakpoint settings
 | ||||
| 		pt.bOn = true; | ||||
| 		pt.bTemporary = temp; | ||||
| 		pt.iAddress = em_address; | ||||
|     if (!IsAddressBreakPoint(em_address)) // only add new addresses
 | ||||
|     { | ||||
|         TBreakPoint pt; // breakpoint settings
 | ||||
|         pt.bOn = true; | ||||
|         pt.bTemporary = temp; | ||||
|         pt.iAddress = em_address; | ||||
| 
 | ||||
| 		m_BreakPoints.push_back(pt); | ||||
|         m_BreakPoints.push_back(pt); | ||||
| 
 | ||||
| 		//if (jit)
 | ||||
| 		//	jit->GetBlockCache()->InvalidateICache(em_address, 4);
 | ||||
| 	} | ||||
|         //if (jit)
 | ||||
|         //    jit->GetBlockCache()->InvalidateICache(em_address, 4);
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void BreakPoints::Remove(u32 em_address) | ||||
| { | ||||
| 	for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | ||||
| 	{ | ||||
| 		if (i->iAddress == em_address) | ||||
| 		{ | ||||
| 			m_BreakPoints.erase(i); | ||||
| 			//if (jit)
 | ||||
| 			//	jit->GetBlockCache()->InvalidateICache(em_address, 4);
 | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
|     for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | ||||
|     { | ||||
|         if (i->iAddress == em_address) | ||||
|         { | ||||
|             m_BreakPoints.erase(i); | ||||
|             //if (jit)
 | ||||
|             //    jit->GetBlockCache()->InvalidateICache(em_address, 4);
 | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void BreakPoints::Clear() | ||||
| { | ||||
| 	//if (jit)
 | ||||
| 	//{
 | ||||
| 	//	std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(),
 | ||||
| 	//		[](const TBreakPoint& bp)
 | ||||
| 	//		{
 | ||||
| 	//			jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 | ||||
| 	//		}
 | ||||
| 	//	);
 | ||||
| 	//}
 | ||||
| 	 | ||||
| 	m_BreakPoints.clear(); | ||||
|     //if (jit)
 | ||||
|     //{
 | ||||
|     //    std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(),
 | ||||
|     //        [](const TBreakPoint& bp)
 | ||||
|     //        {
 | ||||
|     //            jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 | ||||
|     //        }
 | ||||
|     //    );
 | ||||
|     //}
 | ||||
|      | ||||
|     m_BreakPoints.clear(); | ||||
| } | ||||
| 
 | ||||
| MemChecks::TMemChecksStr MemChecks::GetStrings() const | ||||
| { | ||||
| 	TMemChecksStr mcs; | ||||
| 	for (TMemChecks::const_iterator i = m_MemChecks.begin(); | ||||
| 		i != m_MemChecks.end(); ++i) | ||||
| 	{ | ||||
| 		std::stringstream mc; | ||||
| 		mc << std::hex << i->StartAddress; | ||||
| 		mc << " " << (i->bRange ? i->EndAddress : i->StartAddress) << " " << | ||||
| 			(i->bRange ? "n" : "") << (i->OnRead ? "r" : "") << | ||||
| 			(i->OnWrite ? "w" : "") << (i->Log ? "l" : "") << (i->Break ? "p" : ""); | ||||
| 		mcs.push_back(mc.str()); | ||||
| 	} | ||||
|     TMemChecksStr mcs; | ||||
|     for (TMemChecks::const_iterator i = m_MemChecks.begin(); | ||||
|         i != m_MemChecks.end(); ++i) | ||||
|     { | ||||
|         std::stringstream mc; | ||||
|         mc << std::hex << i->StartAddress; | ||||
|         mc << " " << (i->bRange ? i->EndAddress : i->StartAddress) << " " << | ||||
|             (i->bRange ? "n" : "") << (i->OnRead ? "r" : "") << | ||||
|             (i->OnWrite ? "w" : "") << (i->Log ? "l" : "") << (i->Break ? "p" : ""); | ||||
|         mcs.push_back(mc.str()); | ||||
|     } | ||||
| 
 | ||||
| 	return mcs; | ||||
|     return mcs; | ||||
| } | ||||
| 
 | ||||
| void MemChecks::AddFromStrings(const TMemChecksStr& mcs) | ||||
| { | ||||
| 	for (TMemChecksStr::const_iterator i = mcs.begin(); i != mcs.end(); ++i) | ||||
| 	{ | ||||
| 		TMemCheck mc; | ||||
| 		std::stringstream mcstr; | ||||
| 		mcstr << std::hex << *i; | ||||
| 		mcstr >> mc.StartAddress; | ||||
| 		mc.bRange	= i->find("n") != i->npos; | ||||
| 		mc.OnRead	= i->find("r") != i->npos; | ||||
| 		mc.OnWrite	= i->find("w") != i->npos; | ||||
| 		mc.Log		= i->find("l") != i->npos; | ||||
| 		mc.Break	= i->find("p") != i->npos; | ||||
| 		if (mc.bRange) | ||||
| 			mcstr >> mc.EndAddress; | ||||
| 		else | ||||
| 			mc.EndAddress = mc.StartAddress; | ||||
| 		Add(mc); | ||||
| 	} | ||||
|     for (TMemChecksStr::const_iterator i = mcs.begin(); i != mcs.end(); ++i) | ||||
|     { | ||||
|         TMemCheck mc; | ||||
|         std::stringstream mcstr; | ||||
|         mcstr << std::hex << *i; | ||||
|         mcstr >> mc.StartAddress; | ||||
|         mc.bRange    = i->find("n") != i->npos; | ||||
|         mc.OnRead    = i->find("r") != i->npos; | ||||
|         mc.OnWrite    = i->find("w") != i->npos; | ||||
|         mc.Log        = i->find("l") != i->npos; | ||||
|         mc.Break    = i->find("p") != i->npos; | ||||
|         if (mc.bRange) | ||||
|             mcstr >> mc.EndAddress; | ||||
|         else | ||||
|             mc.EndAddress = mc.StartAddress; | ||||
|         Add(mc); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void MemChecks::Add(const TMemCheck& _rMemoryCheck) | ||||
| { | ||||
| 	if (GetMemCheck(_rMemoryCheck.StartAddress) == 0) | ||||
| 		m_MemChecks.push_back(_rMemoryCheck); | ||||
|     if (GetMemCheck(_rMemoryCheck.StartAddress) == 0) | ||||
|         m_MemChecks.push_back(_rMemoryCheck); | ||||
| } | ||||
| 
 | ||||
| void MemChecks::Remove(u32 _Address) | ||||
| { | ||||
| 	for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) | ||||
| 	{ | ||||
| 		if (i->StartAddress == _Address) | ||||
| 		{ | ||||
| 			m_MemChecks.erase(i); | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
|     for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) | ||||
|     { | ||||
|         if (i->StartAddress == _Address) | ||||
|         { | ||||
|             m_MemChecks.erase(i); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| TMemCheck *MemChecks::GetMemCheck(u32 address) | ||||
| { | ||||
| 	for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) | ||||
| 	{ | ||||
| 		if (i->bRange) | ||||
| 		{ | ||||
| 			if (address >= i->StartAddress && address <= i->EndAddress) | ||||
| 				return &(*i); | ||||
| 		} | ||||
| 		else if (i->StartAddress == address) | ||||
| 			return &(*i); | ||||
| 	} | ||||
|     for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) | ||||
|     { | ||||
|         if (i->bRange) | ||||
|         { | ||||
|             if (address >= i->StartAddress && address <= i->EndAddress) | ||||
|                 return &(*i); | ||||
|         } | ||||
|         else if (i->StartAddress == address) | ||||
|             return &(*i); | ||||
|     } | ||||
| 
 | ||||
| 	// none found
 | ||||
| 	return 0; | ||||
|     // none found
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| void TMemCheck::Action(DebugInterface *debug_interface, u32 iValue, u32 addr, | ||||
| 						bool write, int size, u32 pc) | ||||
|                         bool write, int size, u32 pc) | ||||
| { | ||||
| 	if ((write && OnWrite) || (!write && OnRead)) | ||||
| 	{ | ||||
| 		if (Log) | ||||
| 		{ | ||||
| 			INFO_LOG(MEMMAP, "CHK %08x (%s) %s%i %0*x at %08x (%s)", | ||||
| 				pc, debug_interface->getDescription(pc).c_str(), | ||||
| 				write ? "Write" : "Read", size*8, size*2, iValue, addr, | ||||
| 				debug_interface->getDescription(addr).c_str() | ||||
| 				); | ||||
| 		} | ||||
| 		if (Break) | ||||
| 			debug_interface->breakNow(); | ||||
| 	} | ||||
|     if ((write && OnWrite) || (!write && OnRead)) | ||||
|     { | ||||
|         if (Log) | ||||
|         { | ||||
|             INFO_LOG(MEMMAP, "CHK %08x (%s) %s%i %0*x at %08x (%s)", | ||||
|                 pc, debug_interface->getDescription(pc).c_str(), | ||||
|                 write ? "Write" : "Read", size*8, size*2, iValue, addr, | ||||
|                 debug_interface->getDescription(addr).c_str() | ||||
|                 ); | ||||
|         } | ||||
|         if (Break) | ||||
|             debug_interface->breakNow(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -14,64 +14,64 @@ class DebugInterface; | |||
| 
 | ||||
| struct TBreakPoint | ||||
| { | ||||
| 	u32		iAddress; | ||||
| 	bool	bOn; | ||||
| 	bool	bTemporary; | ||||
|     u32        iAddress; | ||||
|     bool    bOn; | ||||
|     bool    bTemporary; | ||||
| }; | ||||
| 
 | ||||
| struct TMemCheck | ||||
| { | ||||
| 	TMemCheck() { | ||||
| 		numHits = 0; | ||||
| 		StartAddress = EndAddress = 0; | ||||
| 		bRange = OnRead = OnWrite = Log = Break = false; | ||||
| 	} | ||||
| 	u32 StartAddress; | ||||
| 	u32 EndAddress; | ||||
|     TMemCheck() { | ||||
|         numHits = 0; | ||||
|         StartAddress = EndAddress = 0; | ||||
|         bRange = OnRead = OnWrite = Log = Break = false; | ||||
|     } | ||||
|     u32 StartAddress; | ||||
|     u32 EndAddress; | ||||
| 
 | ||||
| 	bool	bRange; | ||||
|     bool    bRange; | ||||
| 
 | ||||
| 	bool	OnRead; | ||||
| 	bool	OnWrite; | ||||
|     bool    OnRead; | ||||
|     bool    OnWrite; | ||||
| 
 | ||||
| 	bool	Log; | ||||
| 	bool	Break; | ||||
|     bool    Log; | ||||
|     bool    Break; | ||||
| 
 | ||||
| 	u32		numHits; | ||||
|     u32        numHits; | ||||
| 
 | ||||
| 	void Action(DebugInterface *dbg_interface, u32 _iValue, u32 addr, | ||||
| 				bool write, int size, u32 pc); | ||||
|     void Action(DebugInterface *dbg_interface, u32 _iValue, u32 addr, | ||||
|                 bool write, int size, u32 pc); | ||||
| }; | ||||
| 
 | ||||
| // Code breakpoints.
 | ||||
| class BreakPoints | ||||
| { | ||||
| public: | ||||
| 	typedef std::vector<TBreakPoint> TBreakPoints; | ||||
| 	typedef std::vector<std::string> TBreakPointsStr; | ||||
|     typedef std::vector<TBreakPoint> TBreakPoints; | ||||
|     typedef std::vector<std::string> TBreakPointsStr; | ||||
| 
 | ||||
| 	const TBreakPoints& GetBreakPoints() { return m_BreakPoints; } | ||||
|     const TBreakPoints& GetBreakPoints() { return m_BreakPoints; } | ||||
| 
 | ||||
| 	TBreakPointsStr GetStrings() const; | ||||
| 	void AddFromStrings(const TBreakPointsStr& bps); | ||||
|     TBreakPointsStr GetStrings() const; | ||||
|     void AddFromStrings(const TBreakPointsStr& bps); | ||||
| 
 | ||||
| 	// is address breakpoint
 | ||||
| 	bool IsAddressBreakPoint(u32 _iAddress); | ||||
| 	bool IsTempBreakPoint(u32 _iAddress); | ||||
|     // is address breakpoint
 | ||||
|     bool IsAddressBreakPoint(u32 _iAddress); | ||||
|     bool IsTempBreakPoint(u32 _iAddress); | ||||
| 
 | ||||
| 	// Add BreakPoint
 | ||||
| 	void Add(u32 em_address, bool temp=false); | ||||
| 	void Add(const TBreakPoint& bp); | ||||
|     // Add BreakPoint
 | ||||
|     void Add(u32 em_address, bool temp=false); | ||||
|     void Add(const TBreakPoint& bp); | ||||
| 
 | ||||
| 	// Remove Breakpoint
 | ||||
| 	void Remove(u32 _iAddress); | ||||
| 	void Clear(); | ||||
|     // Remove Breakpoint
 | ||||
|     void Remove(u32 _iAddress); | ||||
|     void Clear(); | ||||
| 
 | ||||
|     void DeleteByAddress(u32 _Address); | ||||
| 
 | ||||
| private: | ||||
| 	TBreakPoints m_BreakPoints; | ||||
| 	u32	m_iBreakOnCount; | ||||
|     TBreakPoints m_BreakPoints; | ||||
|     u32    m_iBreakOnCount; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -79,23 +79,23 @@ private: | |||
| class MemChecks | ||||
| { | ||||
| public: | ||||
| 	typedef std::vector<TMemCheck> TMemChecks; | ||||
| 	typedef std::vector<std::string> TMemChecksStr; | ||||
|     typedef std::vector<TMemCheck> TMemChecks; | ||||
|     typedef std::vector<std::string> TMemChecksStr; | ||||
| 
 | ||||
| 	TMemChecks m_MemChecks; | ||||
|     TMemChecks m_MemChecks; | ||||
| 
 | ||||
| 	const TMemChecks& GetMemChecks() { return m_MemChecks; } | ||||
|     const TMemChecks& GetMemChecks() { return m_MemChecks; } | ||||
| 
 | ||||
| 	TMemChecksStr GetStrings() const; | ||||
| 	void AddFromStrings(const TMemChecksStr& mcs); | ||||
|     TMemChecksStr GetStrings() const; | ||||
|     void AddFromStrings(const TMemChecksStr& mcs); | ||||
| 
 | ||||
| 	void Add(const TMemCheck& _rMemoryCheck); | ||||
|     void Add(const TMemCheck& _rMemoryCheck); | ||||
| 
 | ||||
| 	// memory breakpoint
 | ||||
| 	TMemCheck *GetMemCheck(u32 address); | ||||
|     // memory breakpoint
 | ||||
|     TMemCheck *GetMemCheck(u32 address); | ||||
|     void Remove(u32 _Address); | ||||
| 
 | ||||
| 	void Clear() { m_MemChecks.clear(); }; | ||||
|     void Clear() { m_MemChecks.clear(); }; | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -34,12 +34,12 @@ extern const char *netplay_dolphin_ver; | |||
| class NonCopyable | ||||
| { | ||||
| protected: | ||||
| 	NonCopyable() {} | ||||
| 	NonCopyable(const NonCopyable&&) {} | ||||
| 	void operator=(const NonCopyable&&) {} | ||||
|     NonCopyable() {} | ||||
|     NonCopyable(const NonCopyable&&) {} | ||||
|     void operator=(const NonCopyable&&) {} | ||||
| private: | ||||
| 	NonCopyable(NonCopyable&); | ||||
| 	NonCopyable& operator=(NonCopyable& other); | ||||
|     NonCopyable(NonCopyable&); | ||||
|     NonCopyable& operator=(NonCopyable& other); | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
|  | @ -61,40 +61,40 @@ private: | |||
| #elif defined _WIN32 | ||||
| 
 | ||||
| // Check MSC ver
 | ||||
| 	#if !defined _MSC_VER || _MSC_VER <= 1000 | ||||
| 		#error needs at least version 1000 of MSC | ||||
| 	#endif | ||||
|     #if !defined _MSC_VER || _MSC_VER <= 1000 | ||||
|         #error needs at least version 1000 of MSC | ||||
|     #endif | ||||
| 
 | ||||
| 	#define NOMINMAX | ||||
|     #define NOMINMAX | ||||
| 
 | ||||
| // Memory leak checks
 | ||||
| 	#define CHECK_HEAP_INTEGRITY() | ||||
|     #define CHECK_HEAP_INTEGRITY() | ||||
| 
 | ||||
| // Alignment
 | ||||
| 	#define MEMORY_ALIGNED16(x) __declspec(align(16)) x | ||||
| 	#define MEMORY_ALIGNED32(x) __declspec(align(32)) x | ||||
| 	#define MEMORY_ALIGNED64(x) __declspec(align(64)) x | ||||
| 	#define MEMORY_ALIGNED128(x) __declspec(align(128)) x | ||||
| 	#define MEMORY_ALIGNED16_DECL(x) __declspec(align(16)) x | ||||
| 	#define MEMORY_ALIGNED64_DECL(x) __declspec(align(64)) x | ||||
|     #define MEMORY_ALIGNED16(x) __declspec(align(16)) x | ||||
|     #define MEMORY_ALIGNED32(x) __declspec(align(32)) x | ||||
|     #define MEMORY_ALIGNED64(x) __declspec(align(64)) x | ||||
|     #define MEMORY_ALIGNED128(x) __declspec(align(128)) x | ||||
|     #define MEMORY_ALIGNED16_DECL(x) __declspec(align(16)) x | ||||
|     #define MEMORY_ALIGNED64_DECL(x) __declspec(align(64)) x | ||||
| 
 | ||||
| // Since they are always around on windows
 | ||||
| 	#define HAVE_WX 1 | ||||
| 	#define HAVE_OPENAL 1 | ||||
|     #define HAVE_WX 1 | ||||
|     #define HAVE_OPENAL 1 | ||||
| 
 | ||||
| 	#define HAVE_PORTAUDIO 1 | ||||
|     #define HAVE_PORTAUDIO 1 | ||||
| 
 | ||||
| // Debug definitions
 | ||||
| 	#if defined(_DEBUG) | ||||
| 		#include <crtdbg.h> | ||||
| 		#undef CHECK_HEAP_INTEGRITY | ||||
| 		#define CHECK_HEAP_INTEGRITY() {if (!_CrtCheckMemory()) PanicAlert("memory corruption detected. see log.");} | ||||
| 		// If you want to see how much a pain in the ass singletons are, for example:
 | ||||
| 		// {614} normal block at 0x030C5310, 188 bytes long.
 | ||||
| 		// Data: <Master Log      > 4D 61 73 74 65 72 20 4C 6F 67 00 00 00 00 00 00
 | ||||
| 		struct CrtDebugBreak { CrtDebugBreak(int spot) { _CrtSetBreakAlloc(spot); } }; | ||||
| 		//CrtDebugBreak breakAt(614);
 | ||||
| 	#endif // end DEBUG/FAST
 | ||||
|     #if defined(_DEBUG) | ||||
|         #include <crtdbg.h> | ||||
|         #undef CHECK_HEAP_INTEGRITY | ||||
|         #define CHECK_HEAP_INTEGRITY() {if (!_CrtCheckMemory()) PanicAlert("memory corruption detected. see log.");} | ||||
|         // If you want to see how much a pain in the ass singletons are, for example:
 | ||||
|         // {614} normal block at 0x030C5310, 188 bytes long.
 | ||||
|         // Data: <Master Log      > 4D 61 73 74 65 72 20 4C 6F 67 00 00 00 00 00 00
 | ||||
|         struct CrtDebugBreak { CrtDebugBreak(int spot) { _CrtSetBreakAlloc(spot); } }; | ||||
|         //CrtDebugBreak breakAt(614);
 | ||||
|     #endif // end DEBUG/FAST
 | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
|  | @ -149,18 +149,18 @@ private: | |||
| // Host communication.
 | ||||
| enum HOST_COMM | ||||
| { | ||||
| 	// Begin at 10 in case there is already messages with wParam = 0, 1, 2 and so on
 | ||||
| 	WM_USER_STOP = 10, | ||||
| 	WM_USER_CREATE, | ||||
| 	WM_USER_SETCURSOR, | ||||
|     // Begin at 10 in case there is already messages with wParam = 0, 1, 2 and so on
 | ||||
|     WM_USER_STOP = 10, | ||||
|     WM_USER_CREATE, | ||||
|     WM_USER_SETCURSOR, | ||||
| }; | ||||
| 
 | ||||
| // Used for notification on emulation state
 | ||||
| enum EMUSTATE_CHANGE | ||||
| { | ||||
| 	EMUSTATE_CHANGE_PLAY = 1, | ||||
| 	EMUSTATE_CHANGE_PAUSE, | ||||
| 	EMUSTATE_CHANGE_STOP | ||||
|     EMUSTATE_CHANGE_PLAY = 1, | ||||
|     EMUSTATE_CHANGE_PAUSE, | ||||
|     EMUSTATE_CHANGE_STOP | ||||
| }; | ||||
| 
 | ||||
| #endif // _COMMON_H_
 | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ template<> struct CompileTimeAssert<true> {}; | |||
| #define b8(x)   ( b4(x) | ( b4(x) >> 4) ) | ||||
| #define b16(x)  ( b8(x) | ( b8(x) >> 8) )   | ||||
| #define b32(x)  (b16(x) | (b16(x) >>16) ) | ||||
| #define ROUND_UP_POW2(x)	(b32(x - 1) + 1) | ||||
| #define ROUND_UP_POW2(x)    (b32(x - 1) + 1) | ||||
| 
 | ||||
| #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) | ||||
| 
 | ||||
|  | @ -29,11 +29,11 @@ template<> struct CompileTimeAssert<true> {}; | |||
| static __inline __m128i __attribute__((__always_inline__)) | ||||
| _mm_shuffle_epi8(__m128i a, __m128i mask) | ||||
| { | ||||
| 	__m128i result; | ||||
| 	__asm__("pshufb %1, %0" | ||||
| 		: "=x" (result) | ||||
| 		: "xm" (mask), "0" (a)); | ||||
| 	return result; | ||||
|     __m128i result; | ||||
|     __asm__("pshufb %1, %0" | ||||
|         : "=x" (result) | ||||
|         : "xm" (mask), "0" (a)); | ||||
|     return result; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | @ -47,103 +47,103 @@ _mm_shuffle_epi8(__m128i a, __m128i mask) | |||
| #endif | ||||
| 
 | ||||
| // go to debugger mode
 | ||||
| 	#ifdef GEKKO | ||||
| 		#define Crash() | ||||
| 	#elif defined _M_GENERIC | ||||
| 		#define Crash() { exit(1); } | ||||
| 	#else | ||||
| 		#define Crash() {asm ("int $3");} | ||||
| 	#endif | ||||
| 	#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) | ||||
|     #ifdef GEKKO | ||||
|         #define Crash() | ||||
|     #elif defined _M_GENERIC | ||||
|         #define Crash() { exit(1); } | ||||
|     #else | ||||
|         #define Crash() {asm ("int $3");} | ||||
|     #endif | ||||
|     #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) | ||||
| // GCC 4.8 defines all the rotate functions now
 | ||||
| // Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit
 | ||||
| #ifndef _rotl | ||||
| inline u32 _rotl(u32 x, int shift) { | ||||
| 	shift &= 31; | ||||
| 	if (!shift) return x; | ||||
| 	return (x << shift) | (x >> (32 - shift)); | ||||
|     shift &= 31; | ||||
|     if (!shift) return x; | ||||
|     return (x << shift) | (x >> (32 - shift)); | ||||
| } | ||||
| 
 | ||||
| inline u32 _rotr(u32 x, int shift) { | ||||
| 	shift &= 31; | ||||
| 	if (!shift) return x; | ||||
| 	return (x >> shift) | (x << (32 - shift)); | ||||
|     shift &= 31; | ||||
|     if (!shift) return x; | ||||
|     return (x >> shift) | (x << (32 - shift)); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| inline u64 _rotl64(u64 x, unsigned int shift){ | ||||
| 	unsigned int n = shift % 64; | ||||
| 	return (x << n) | (x >> (64 - n)); | ||||
|     unsigned int n = shift % 64; | ||||
|     return (x << n) | (x >> (64 - n)); | ||||
| } | ||||
| 
 | ||||
| inline u64 _rotr64(u64 x, unsigned int shift){ | ||||
| 	unsigned int n = shift % 64; | ||||
| 	return (x >> n) | (x << (64 - n)); | ||||
|     unsigned int n = shift % 64; | ||||
|     return (x >> n) | (x << (64 - n)); | ||||
| } | ||||
| 
 | ||||
| #else // WIN32
 | ||||
| // Function Cross-Compatibility
 | ||||
| 	#define strcasecmp _stricmp | ||||
| 	#define strncasecmp _strnicmp | ||||
| 	#define unlink _unlink | ||||
| 	#define snprintf _snprintf | ||||
| 	#define vscprintf _vscprintf | ||||
| 	 | ||||
|     #define strcasecmp _stricmp | ||||
|     #define strncasecmp _strnicmp | ||||
|     #define unlink _unlink | ||||
|     #define snprintf _snprintf | ||||
|     #define vscprintf _vscprintf | ||||
|      | ||||
| // Locale Cross-Compatibility
 | ||||
| 	#define locale_t _locale_t | ||||
| 	#define freelocale _free_locale | ||||
| 	#define newlocale(mask, locale, base) _create_locale(mask, locale) | ||||
| 	 | ||||
| 	#define LC_GLOBAL_LOCALE	((locale_t)-1) | ||||
| 	#define LC_ALL_MASK			LC_ALL | ||||
| 	#define LC_COLLATE_MASK		LC_COLLATE | ||||
| 	#define LC_CTYPE_MASK		LC_CTYPE | ||||
| 	#define LC_MONETARY_MASK	LC_MONETARY | ||||
| 	#define LC_NUMERIC_MASK		LC_NUMERIC | ||||
| 	#define LC_TIME_MASK		LC_TIME | ||||
| 	 | ||||
| 	inline locale_t uselocale(locale_t new_locale) | ||||
| 	{ | ||||
| 		// Retrieve the current per thread locale setting
 | ||||
| 		bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE); | ||||
|     #define locale_t _locale_t | ||||
|     #define freelocale _free_locale | ||||
|     #define newlocale(mask, locale, base) _create_locale(mask, locale) | ||||
|      | ||||
|     #define LC_GLOBAL_LOCALE    ((locale_t)-1) | ||||
|     #define LC_ALL_MASK            LC_ALL | ||||
|     #define LC_COLLATE_MASK        LC_COLLATE | ||||
|     #define LC_CTYPE_MASK        LC_CTYPE | ||||
|     #define LC_MONETARY_MASK    LC_MONETARY | ||||
|     #define LC_NUMERIC_MASK        LC_NUMERIC | ||||
|     #define LC_TIME_MASK        LC_TIME | ||||
|      | ||||
|     inline locale_t uselocale(locale_t new_locale) | ||||
|     { | ||||
|         // Retrieve the current per thread locale setting
 | ||||
|         bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE); | ||||
| 
 | ||||
| 		// Retrieve the current thread-specific locale
 | ||||
| 		locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE; | ||||
|         // Retrieve the current thread-specific locale
 | ||||
|         locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE; | ||||
| 
 | ||||
| 		if(new_locale == LC_GLOBAL_LOCALE) | ||||
| 		{ | ||||
| 			// Restore the global locale
 | ||||
| 			_configthreadlocale(_DISABLE_PER_THREAD_LOCALE); | ||||
| 		} | ||||
| 		else if(new_locale != NULL) | ||||
| 		{ | ||||
| 			// Configure the thread to set the locale only for this thread
 | ||||
| 			_configthreadlocale(_ENABLE_PER_THREAD_LOCALE); | ||||
|         if(new_locale == LC_GLOBAL_LOCALE) | ||||
|         { | ||||
|             // Restore the global locale
 | ||||
|             _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); | ||||
|         } | ||||
|         else if(new_locale != NULL) | ||||
|         { | ||||
|             // Configure the thread to set the locale only for this thread
 | ||||
|             _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); | ||||
| 
 | ||||
| 			// Set all locale categories
 | ||||
| 			for(int i = LC_MIN; i <= LC_MAX; i++) | ||||
| 				setlocale(i, new_locale->locinfo->lc_category[i].locale); | ||||
| 		} | ||||
|             // Set all locale categories
 | ||||
|             for(int i = LC_MIN; i <= LC_MAX; i++) | ||||
|                 setlocale(i, new_locale->locinfo->lc_category[i].locale); | ||||
|         } | ||||
| 
 | ||||
| 		return old_locale; | ||||
| 	} | ||||
|         return old_locale; | ||||
|     } | ||||
| 
 | ||||
| // 64 bit offsets for windows
 | ||||
| 	#define fseeko _fseeki64 | ||||
| 	#define ftello _ftelli64 | ||||
| 	#define atoll _atoi64 | ||||
| 	#define stat64 _stat64 | ||||
| 	#define fstat64 _fstat64 | ||||
| 	#define fileno _fileno | ||||
|     #define fseeko _fseeki64 | ||||
|     #define ftello _ftelli64 | ||||
|     #define atoll _atoi64 | ||||
|     #define stat64 _stat64 | ||||
|     #define fstat64 _fstat64 | ||||
|     #define fileno _fileno | ||||
| 
 | ||||
| 	#if _M_IX86 | ||||
| 		#define Crash() {__asm int 3} | ||||
| 	#else | ||||
|     #if _M_IX86 | ||||
|         #define Crash() {__asm int 3} | ||||
|     #else | ||||
| extern "C" { | ||||
| 	__declspec(dllimport) void __stdcall DebugBreak(void); | ||||
|     __declspec(dllimport) void __stdcall DebugBreak(void); | ||||
| } | ||||
| 		#define Crash() {DebugBreak();} | ||||
| 	#endif // M_IX86
 | ||||
|         #define Crash() {DebugBreak();} | ||||
|     #endif // M_IX86
 | ||||
| #endif // WIN32 ndef
 | ||||
| 
 | ||||
| // Dolphin's min and max functions
 | ||||
|  | @ -186,11 +186,11 @@ inline u32 swap32(u32 _data) {return bswap_32(_data);} | |||
| inline u64 swap64(u64 _data) {return bswap_64(_data);} | ||||
| #elif __APPLE__ | ||||
| inline __attribute__((always_inline)) u16 swap16(u16 _data) | ||||
| 	{return (_data >> 8) | (_data << 8);} | ||||
|     {return (_data >> 8) | (_data << 8);} | ||||
| inline __attribute__((always_inline)) u32 swap32(u32 _data) | ||||
| 	{return __builtin_bswap32(_data);} | ||||
|     {return __builtin_bswap32(_data);} | ||||
| inline __attribute__((always_inline)) u64 swap64(u64 _data) | ||||
| 	{return __builtin_bswap64(_data);} | ||||
|     {return __builtin_bswap64(_data);} | ||||
| #elif __FreeBSD__ | ||||
| inline u16 swap16(u16 _data) {return bswap16(_data);} | ||||
| inline u32 swap32(u32 _data) {return bswap32(_data);} | ||||
|  | @ -216,28 +216,28 @@ inline void swap<1>(u8* data) | |||
| template <> | ||||
| inline void swap<2>(u8* data) | ||||
| { | ||||
| 	*reinterpret_cast<u16*>(data) = swap16(data); | ||||
|     *reinterpret_cast<u16*>(data) = swap16(data); | ||||
| } | ||||
| 
 | ||||
| template <> | ||||
| inline void swap<4>(u8* data) | ||||
| { | ||||
| 	*reinterpret_cast<u32*>(data) = swap32(data); | ||||
|     *reinterpret_cast<u32*>(data) = swap32(data); | ||||
| } | ||||
| 
 | ||||
| template <> | ||||
| inline void swap<8>(u8* data) | ||||
| { | ||||
| 	*reinterpret_cast<u64*>(data) = swap64(data); | ||||
|     *reinterpret_cast<u64*>(data) = swap64(data); | ||||
| } | ||||
| 
 | ||||
| template <typename T> | ||||
| inline T FromBigEndian(T data) | ||||
| { | ||||
| 	//static_assert(std::is_arithmetic<T>::value, "function only makes sense with arithmetic types");
 | ||||
| 	 | ||||
| 	swap<sizeof(data)>(reinterpret_cast<u8*>(&data)); | ||||
| 	return data; | ||||
|     //static_assert(std::is_arithmetic<T>::value, "function only makes sense with arithmetic types");
 | ||||
|      | ||||
|     swap<sizeof(data)>(reinterpret_cast<u8*>(&data)); | ||||
|     return data; | ||||
| } | ||||
| 
 | ||||
| }  // Namespace Common
 | ||||
|  |  | |||
|  | @ -13,34 +13,34 @@ | |||
| #define DIR_SEP_CHR '/' | ||||
| 
 | ||||
| #ifndef MAX_PATH | ||||
| #define MAX_PATH	260 | ||||
| #define MAX_PATH    260 | ||||
| #endif | ||||
| 
 | ||||
| // The user data dir
 | ||||
| #define ROOT_DIR "." | ||||
| #ifdef _WIN32 | ||||
| 	#define USERDATA_DIR "user" | ||||
| 	#define EMU_DATA_DIR "emu" | ||||
|     #define USERDATA_DIR "user" | ||||
|     #define EMU_DATA_DIR "emu" | ||||
| #else | ||||
| 	#define USERDATA_DIR "user" | ||||
| 	#ifdef USER_DIR | ||||
| 		#define EMU_DATA_DIR USER_DIR | ||||
| 	#else | ||||
| 		#define EMU_DATA_DIR ".emu" | ||||
| 	#endif | ||||
|     #define USERDATA_DIR "user" | ||||
|     #ifdef USER_DIR | ||||
|         #define EMU_DATA_DIR USER_DIR | ||||
|     #else | ||||
|         #define EMU_DATA_DIR ".emu" | ||||
|     #endif | ||||
| #endif | ||||
| 
 | ||||
| // Shared data dirs (Sys and shared User for linux)
 | ||||
| #ifdef _WIN32 | ||||
| 	#define SYSDATA_DIR "sys" | ||||
|     #define SYSDATA_DIR "sys" | ||||
| #else | ||||
| 	#ifdef DATA_DIR | ||||
| 		#define SYSDATA_DIR DATA_DIR "sys" | ||||
| 		#define SHARED_USER_DIR  DATA_DIR USERDATA_DIR DIR_SEP | ||||
| 	#else | ||||
| 		#define SYSDATA_DIR "sys" | ||||
| 		#define SHARED_USER_DIR  ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP | ||||
| 	#endif | ||||
|     #ifdef DATA_DIR | ||||
|         #define SYSDATA_DIR DATA_DIR "sys" | ||||
|         #define SHARED_USER_DIR  DATA_DIR USERDATA_DIR DIR_SEP | ||||
|     #else | ||||
|         #define SYSDATA_DIR "sys" | ||||
|         #define SHARED_USER_DIR  ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP | ||||
|     #endif | ||||
| #endif | ||||
| 
 | ||||
| // Dirs in both User and Sys
 | ||||
|  | @ -49,31 +49,31 @@ | |||
| #define JAP_DIR "JAP" | ||||
| 
 | ||||
| // Subdirs in the User dir returned by GetUserPath(D_USER_IDX)
 | ||||
| #define CONFIG_DIR			"config" | ||||
| #define GAMECONFIG_DIR		"game_config" | ||||
| #define MAPS_DIR			"maps" | ||||
| #define CACHE_DIR			"cache" | ||||
| #define SHADERCACHE_DIR		"shader_cache" | ||||
| #define STATESAVES_DIR		"state_saves" | ||||
| #define SCREENSHOTS_DIR		"screenShots" | ||||
| #define DUMP_DIR			"dump" | ||||
| #define DUMP_TEXTURES_DIR	"textures" | ||||
| #define DUMP_FRAMES_DIR		"frames" | ||||
| #define DUMP_AUDIO_DIR		"audio" | ||||
| #define LOGS_DIR			"logs" | ||||
| #define SHADERS_DIR 		"shaders" | ||||
| #define SYSCONF_DIR 		"sysconf" | ||||
| #define CONFIG_DIR            "config" | ||||
| #define GAMECONFIG_DIR        "game_config" | ||||
| #define MAPS_DIR            "maps" | ||||
| #define CACHE_DIR            "cache" | ||||
| #define SHADERCACHE_DIR        "shader_cache" | ||||
| #define STATESAVES_DIR        "state_saves" | ||||
| #define SCREENSHOTS_DIR        "screenShots" | ||||
| #define DUMP_DIR            "dump" | ||||
| #define DUMP_TEXTURES_DIR    "textures" | ||||
| #define DUMP_FRAMES_DIR        "frames" | ||||
| #define DUMP_AUDIO_DIR        "audio" | ||||
| #define LOGS_DIR            "logs" | ||||
| #define SHADERS_DIR         "shaders" | ||||
| #define SYSCONF_DIR         "sysconf" | ||||
| 
 | ||||
| // Filenames
 | ||||
| // Files in the directory returned by GetUserPath(D_CONFIG_IDX)
 | ||||
| #define EMU_CONFIG		"emu.ini" | ||||
| #define DEBUGGER_CONFIG	"debugger.ini" | ||||
| #define LOGGER_CONFIG	"logger.ini" | ||||
| #define EMU_CONFIG        "emu.ini" | ||||
| #define DEBUGGER_CONFIG    "debugger.ini" | ||||
| #define LOGGER_CONFIG    "logger.ini" | ||||
| 
 | ||||
| // Files in the directory returned by GetUserPath(D_LOGS_IDX)
 | ||||
| #define MAIN_LOG	"emu.log" | ||||
| #define MAIN_LOG    "emu.log" | ||||
| 
 | ||||
| // Files in the directory returned by GetUserPath(D_SYSCONF_IDX)
 | ||||
| #define SYSCONF	"SYSCONF" | ||||
| #define SYSCONF    "SYSCONF" | ||||
| 
 | ||||
| #endif // _COMMON_PATHS_H_
 | ||||
|  |  | |||
|  | @ -20,16 +20,16 @@ | |||
| ConsoleListener::ConsoleListener() | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	hConsole = NULL; | ||||
| 	bUseColor = true; | ||||
|     hConsole = NULL; | ||||
|     bUseColor = true; | ||||
| #else | ||||
| 	bUseColor = isatty(fileno(stdout)); | ||||
|     bUseColor = isatty(fileno(stdout)); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| ConsoleListener::~ConsoleListener() | ||||
| { | ||||
| 	Close(); | ||||
|     Close(); | ||||
| } | ||||
| 
 | ||||
| // 100, 100, "Dolphin Log Console"
 | ||||
|  | @ -38,31 +38,31 @@ ConsoleListener::~ConsoleListener() | |||
| void ConsoleListener::Open(bool Hidden, int Width, int Height, const char *Title) | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	if (!GetConsoleWindow()) | ||||
| 	{ | ||||
| 		// Open the console window and create the window handle for GetStdHandle()
 | ||||
| 		AllocConsole(); | ||||
| 		// Hide
 | ||||
| 		if (Hidden) ShowWindow(GetConsoleWindow(), SW_HIDE); | ||||
| 		// Save the window handle that AllocConsole() created
 | ||||
| 		hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
| 		// Set the console window title
 | ||||
| 		SetConsoleTitle(UTF8ToTStr(Title).c_str()); | ||||
| 		// Set letter space
 | ||||
| 		LetterSpace(80, 4000); | ||||
| 		//MoveWindow(GetConsoleWindow(), 200,200, 800,800, true);
 | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
| 	} | ||||
|     if (!GetConsoleWindow()) | ||||
|     { | ||||
|         // Open the console window and create the window handle for GetStdHandle()
 | ||||
|         AllocConsole(); | ||||
|         // Hide
 | ||||
|         if (Hidden) ShowWindow(GetConsoleWindow(), SW_HIDE); | ||||
|         // Save the window handle that AllocConsole() created
 | ||||
|         hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
|         // Set the console window title
 | ||||
|         SetConsoleTitle(UTF8ToTStr(Title).c_str()); | ||||
|         // Set letter space
 | ||||
|         LetterSpace(80, 4000); | ||||
|         //MoveWindow(GetConsoleWindow(), 200,200, 800,800, true);
 | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void ConsoleListener::UpdateHandle() | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
|     hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  | @ -70,267 +70,267 @@ void ConsoleListener::UpdateHandle() | |||
| void ConsoleListener::Close() | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	if (hConsole == NULL) | ||||
| 		return; | ||||
| 	FreeConsole(); | ||||
| 	hConsole = NULL; | ||||
|     if (hConsole == NULL) | ||||
|         return; | ||||
|     FreeConsole(); | ||||
|     hConsole = NULL; | ||||
| #else | ||||
| 	fflush(NULL); | ||||
|     fflush(NULL); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| bool ConsoleListener::IsOpen() | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	return (hConsole != NULL); | ||||
|     return (hConsole != NULL); | ||||
| #else | ||||
| 	return true; | ||||
|     return true; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|   LetterSpace: SetConsoleScreenBufferSize and SetConsoleWindowInfo are | ||||
| 	dependent on each other, that's the reason for the additional checks.   | ||||
|     dependent on each other, that's the reason for the additional checks.   | ||||
| */ | ||||
| void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst) | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	BOOL SB, SW; | ||||
| 	if (BufferFirst) | ||||
| 	{ | ||||
| 		// Change screen buffer size
 | ||||
| 		COORD Co = {BufferWidth, BufferHeight}; | ||||
| 		SB = SetConsoleScreenBufferSize(hConsole, Co); | ||||
| 		// Change the screen buffer window size
 | ||||
| 		SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom
 | ||||
| 		SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		// Change the screen buffer window size
 | ||||
| 		SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom
 | ||||
| 		SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); | ||||
| 		// Change screen buffer size
 | ||||
| 		COORD Co = {BufferWidth, BufferHeight}; | ||||
| 		SB = SetConsoleScreenBufferSize(hConsole, Co); | ||||
| 	} | ||||
|     BOOL SB, SW; | ||||
|     if (BufferFirst) | ||||
|     { | ||||
|         // Change screen buffer size
 | ||||
|         COORD Co = {BufferWidth, BufferHeight}; | ||||
|         SB = SetConsoleScreenBufferSize(hConsole, Co); | ||||
|         // Change the screen buffer window size
 | ||||
|         SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom
 | ||||
|         SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // Change the screen buffer window size
 | ||||
|         SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom
 | ||||
|         SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); | ||||
|         // Change screen buffer size
 | ||||
|         COORD Co = {BufferWidth, BufferHeight}; | ||||
|         SB = SetConsoleScreenBufferSize(hConsole, Co); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| void ConsoleListener::LetterSpace(int Width, int Height) | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	// Get console info
 | ||||
| 	CONSOLE_SCREEN_BUFFER_INFO ConInfo; | ||||
| 	GetConsoleScreenBufferInfo(hConsole, &ConInfo); | ||||
|     // Get console info
 | ||||
|     CONSOLE_SCREEN_BUFFER_INFO ConInfo; | ||||
|     GetConsoleScreenBufferInfo(hConsole, &ConInfo); | ||||
| 
 | ||||
| 	//
 | ||||
| 	int OldBufferWidth = ConInfo.dwSize.X; | ||||
| 	int OldBufferHeight = ConInfo.dwSize.Y; | ||||
| 	int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left); | ||||
| 	int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top); | ||||
| 	//
 | ||||
| 	int NewBufferWidth = Width; | ||||
| 	int NewBufferHeight = Height; | ||||
| 	int NewScreenWidth = NewBufferWidth - 1; | ||||
| 	int NewScreenHeight = OldScreenHeight; | ||||
|     //
 | ||||
|     int OldBufferWidth = ConInfo.dwSize.X; | ||||
|     int OldBufferHeight = ConInfo.dwSize.Y; | ||||
|     int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left); | ||||
|     int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top); | ||||
|     //
 | ||||
|     int NewBufferWidth = Width; | ||||
|     int NewBufferHeight = Height; | ||||
|     int NewScreenWidth = NewBufferWidth - 1; | ||||
|     int NewScreenHeight = OldScreenHeight; | ||||
| 
 | ||||
| 	// Width
 | ||||
| 	BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1)); | ||||
| 	// Height
 | ||||
| 	BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1)); | ||||
|     // Width
 | ||||
|     BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1)); | ||||
|     // Height
 | ||||
|     BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1)); | ||||
| 
 | ||||
| 	// Resize the window too
 | ||||
| 	//MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true);
 | ||||
|     // Resize the window too
 | ||||
|     //MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true);
 | ||||
| #endif | ||||
| } | ||||
| #ifdef _WIN32 | ||||
| COORD ConsoleListener::GetCoordinates(int BytesRead, int BufferWidth) | ||||
| { | ||||
| 	COORD Ret = {0, 0}; | ||||
| 	// Full rows
 | ||||
| 	int Step = (int)floor((float)BytesRead / (float)BufferWidth); | ||||
| 	Ret.Y += Step; | ||||
| 	// Partial row
 | ||||
| 	Ret.X = BytesRead - (BufferWidth * Step); | ||||
| 	return Ret; | ||||
|     COORD Ret = {0, 0}; | ||||
|     // Full rows
 | ||||
|     int Step = (int)floor((float)BytesRead / (float)BufferWidth); | ||||
|     Ret.Y += Step; | ||||
|     // Partial row
 | ||||
|     Ret.X = BytesRead - (BufferWidth * Step); | ||||
|     return Ret; | ||||
| } | ||||
| #endif | ||||
| void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize) | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	// Check size
 | ||||
| 	if (Width < 8 || Height < 12) return; | ||||
|     // Check size
 | ||||
|     if (Width < 8 || Height < 12) return; | ||||
| 
 | ||||
| 	bool DBef = true; | ||||
| 	bool DAft = true; | ||||
| 	std::string SLog = ""; | ||||
|     bool DBef = true; | ||||
|     bool DAft = true; | ||||
|     std::string SLog = ""; | ||||
| 
 | ||||
| 	const HWND hWnd = GetConsoleWindow(); | ||||
| 	const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
|     const HWND hWnd = GetConsoleWindow(); | ||||
|     const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
| 
 | ||||
| 	// Get console info
 | ||||
| 	CONSOLE_SCREEN_BUFFER_INFO ConInfo; | ||||
| 	GetConsoleScreenBufferInfo(hConsole, &ConInfo); | ||||
| 	DWORD BufferSize = ConInfo.dwSize.X * ConInfo.dwSize.Y; | ||||
|     // Get console info
 | ||||
|     CONSOLE_SCREEN_BUFFER_INFO ConInfo; | ||||
|     GetConsoleScreenBufferInfo(hConsole, &ConInfo); | ||||
|     DWORD BufferSize = ConInfo.dwSize.X * ConInfo.dwSize.Y; | ||||
| 
 | ||||
| 	// ---------------------------------------------------------------------
 | ||||
| 	//  Save the current text
 | ||||
| 	// ------------------------
 | ||||
| 	DWORD cCharsRead = 0; | ||||
| 	COORD coordScreen = { 0, 0 }; | ||||
|     // ---------------------------------------------------------------------
 | ||||
|     //  Save the current text
 | ||||
|     // ------------------------
 | ||||
|     DWORD cCharsRead = 0; | ||||
|     COORD coordScreen = { 0, 0 }; | ||||
| 
 | ||||
| 	static const int MAX_BYTES = 1024 * 16; | ||||
|     static const int MAX_BYTES = 1024 * 16; | ||||
| 
 | ||||
| 	std::vector<std::array<TCHAR, MAX_BYTES>> Str; | ||||
| 	std::vector<std::array<WORD, MAX_BYTES>> Attr; | ||||
|     std::vector<std::array<TCHAR, MAX_BYTES>> Str; | ||||
|     std::vector<std::array<WORD, MAX_BYTES>> Attr; | ||||
| 
 | ||||
| 	// ReadConsoleOutputAttribute seems to have a limit at this level
 | ||||
| 	static const int ReadBufferSize = MAX_BYTES - 32; | ||||
|     // ReadConsoleOutputAttribute seems to have a limit at this level
 | ||||
|     static const int ReadBufferSize = MAX_BYTES - 32; | ||||
| 
 | ||||
| 	DWORD cAttrRead = ReadBufferSize; | ||||
| 	DWORD BytesRead = 0; | ||||
| 	while (BytesRead < BufferSize) | ||||
| 	{ | ||||
| 		Str.resize(Str.size() + 1); | ||||
| 		if (!ReadConsoleOutputCharacter(hConsole, Str.back().data(), ReadBufferSize, coordScreen, &cCharsRead)) | ||||
| 			SLog += StringFromFormat("WriteConsoleOutputCharacter error"); | ||||
|     DWORD cAttrRead = ReadBufferSize; | ||||
|     DWORD BytesRead = 0; | ||||
|     while (BytesRead < BufferSize) | ||||
|     { | ||||
|         Str.resize(Str.size() + 1); | ||||
|         if (!ReadConsoleOutputCharacter(hConsole, Str.back().data(), ReadBufferSize, coordScreen, &cCharsRead)) | ||||
|             SLog += StringFromFormat("WriteConsoleOutputCharacter error"); | ||||
| 
 | ||||
| 		Attr.resize(Attr.size() + 1); | ||||
| 		if (!ReadConsoleOutputAttribute(hConsole, Attr.back().data(), ReadBufferSize, coordScreen, &cAttrRead)) | ||||
| 			SLog += StringFromFormat("WriteConsoleOutputAttribute error"); | ||||
|         Attr.resize(Attr.size() + 1); | ||||
|         if (!ReadConsoleOutputAttribute(hConsole, Attr.back().data(), ReadBufferSize, coordScreen, &cAttrRead)) | ||||
|             SLog += StringFromFormat("WriteConsoleOutputAttribute error"); | ||||
| 
 | ||||
| 		// Break on error
 | ||||
| 		if (cAttrRead == 0) break; | ||||
| 		BytesRead += cAttrRead; | ||||
| 		coordScreen = GetCoordinates(BytesRead, ConInfo.dwSize.X); | ||||
| 	} | ||||
| 	// Letter space
 | ||||
| 	int LWidth = (int)(floor((float)Width / 8.0f) - 1.0f); | ||||
| 	int LHeight = (int)(floor((float)Height / 12.0f) - 1.0f); | ||||
| 	int LBufWidth = LWidth + 1; | ||||
| 	int LBufHeight = (int)floor((float)BufferSize / (float)LBufWidth); | ||||
| 	// Change screen buffer size
 | ||||
| 	LetterSpace(LBufWidth, LBufHeight); | ||||
|         // Break on error
 | ||||
|         if (cAttrRead == 0) break; | ||||
|         BytesRead += cAttrRead; | ||||
|         coordScreen = GetCoordinates(BytesRead, ConInfo.dwSize.X); | ||||
|     } | ||||
|     // Letter space
 | ||||
|     int LWidth = (int)(floor((float)Width / 8.0f) - 1.0f); | ||||
|     int LHeight = (int)(floor((float)Height / 12.0f) - 1.0f); | ||||
|     int LBufWidth = LWidth + 1; | ||||
|     int LBufHeight = (int)floor((float)BufferSize / (float)LBufWidth); | ||||
|     // Change screen buffer size
 | ||||
|     LetterSpace(LBufWidth, LBufHeight); | ||||
| 
 | ||||
| 
 | ||||
| 	ClearScreen(true); | ||||
| 	coordScreen.Y = 0; | ||||
| 	coordScreen.X = 0; | ||||
| 	DWORD cCharsWritten = 0; | ||||
|     ClearScreen(true); | ||||
|     coordScreen.Y = 0; | ||||
|     coordScreen.X = 0; | ||||
|     DWORD cCharsWritten = 0; | ||||
| 
 | ||||
| 	int BytesWritten = 0; | ||||
| 	DWORD cAttrWritten = 0; | ||||
| 	for (size_t i = 0; i < Attr.size(); i++) | ||||
| 	{ | ||||
| 		if (!WriteConsoleOutputCharacter(hConsole, Str[i].data(), ReadBufferSize, coordScreen, &cCharsWritten)) | ||||
| 			SLog += StringFromFormat("WriteConsoleOutputCharacter error"); | ||||
| 		if (!WriteConsoleOutputAttribute(hConsole, Attr[i].data(), ReadBufferSize, coordScreen, &cAttrWritten)) | ||||
| 			SLog += StringFromFormat("WriteConsoleOutputAttribute error"); | ||||
|     int BytesWritten = 0; | ||||
|     DWORD cAttrWritten = 0; | ||||
|     for (size_t i = 0; i < Attr.size(); i++) | ||||
|     { | ||||
|         if (!WriteConsoleOutputCharacter(hConsole, Str[i].data(), ReadBufferSize, coordScreen, &cCharsWritten)) | ||||
|             SLog += StringFromFormat("WriteConsoleOutputCharacter error"); | ||||
|         if (!WriteConsoleOutputAttribute(hConsole, Attr[i].data(), ReadBufferSize, coordScreen, &cAttrWritten)) | ||||
|             SLog += StringFromFormat("WriteConsoleOutputAttribute error"); | ||||
| 
 | ||||
| 		BytesWritten += cAttrWritten; | ||||
| 		coordScreen = GetCoordinates(BytesWritten, LBufWidth); | ||||
| 	}	 | ||||
|         BytesWritten += cAttrWritten; | ||||
|         coordScreen = GetCoordinates(BytesWritten, LBufWidth); | ||||
|     }     | ||||
| 
 | ||||
| 	const int OldCursor = ConInfo.dwCursorPosition.Y * ConInfo.dwSize.X + ConInfo.dwCursorPosition.X; | ||||
| 	COORD Coo = GetCoordinates(OldCursor, LBufWidth); | ||||
| 	SetConsoleCursorPosition(hConsole, Coo); | ||||
|     const int OldCursor = ConInfo.dwCursorPosition.Y * ConInfo.dwSize.X + ConInfo.dwCursorPosition.X; | ||||
|     COORD Coo = GetCoordinates(OldCursor, LBufWidth); | ||||
|     SetConsoleCursorPosition(hConsole, Coo); | ||||
| 
 | ||||
| 	if (SLog.length() > 0) Log(LogTypes::LNOTICE, SLog.c_str()); | ||||
|     if (SLog.length() > 0) Log(LogTypes::LNOTICE, SLog.c_str()); | ||||
| 
 | ||||
| 	// Resize the window too
 | ||||
| 	if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 100),Height, true); | ||||
|     // Resize the window too
 | ||||
|     if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 100),Height, true); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text) | ||||
| { | ||||
| #if defined(_WIN32) | ||||
| 	/*
 | ||||
| 	const int MAX_BYTES = 1024*10; | ||||
| 	char Str[MAX_BYTES]; | ||||
| 	va_list ArgPtr; | ||||
| 	int Cnt; | ||||
| 	va_start(ArgPtr, Text); | ||||
| 	Cnt = vsnprintf(Str, MAX_BYTES, Text, ArgPtr); | ||||
| 	va_end(ArgPtr); | ||||
| 	*/ | ||||
| 	DWORD cCharsWritten; | ||||
| 	WORD Color; | ||||
|     /*
 | ||||
|     const int MAX_BYTES = 1024*10; | ||||
|     char Str[MAX_BYTES]; | ||||
|     va_list ArgPtr; | ||||
|     int Cnt; | ||||
|     va_start(ArgPtr, Text); | ||||
|     Cnt = vsnprintf(Str, MAX_BYTES, Text, ArgPtr); | ||||
|     va_end(ArgPtr); | ||||
|     */ | ||||
|     DWORD cCharsWritten; | ||||
|     WORD Color; | ||||
| 
 | ||||
| 	switch (Level) | ||||
| 	{ | ||||
| 	case NOTICE_LEVEL: // light green
 | ||||
| 		Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY; | ||||
| 		break; | ||||
| 	case ERROR_LEVEL: // light red
 | ||||
| 		Color = FOREGROUND_RED | FOREGROUND_INTENSITY; | ||||
| 		break; | ||||
| 	case WARNING_LEVEL: // light yellow
 | ||||
| 		Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; | ||||
| 		break; | ||||
| 	case INFO_LEVEL: // cyan
 | ||||
| 		Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; | ||||
| 		break; | ||||
| 	case DEBUG_LEVEL: // gray
 | ||||
| 		Color = FOREGROUND_INTENSITY; | ||||
| 		break; | ||||
| 	default: // off-white
 | ||||
| 		Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; | ||||
| 		break; | ||||
| 	} | ||||
| 	if (strlen(Text) > 10) | ||||
| 	{ | ||||
| 		// First 10 chars white
 | ||||
| 		SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); | ||||
| 		WriteConsole(hConsole, Text, 10, &cCharsWritten, NULL); | ||||
| 		Text += 10; | ||||
| 	} | ||||
| 	SetConsoleTextAttribute(hConsole, Color); | ||||
| 	WriteConsole(hConsole, Text, (DWORD)strlen(Text), &cCharsWritten, NULL); | ||||
|     switch (Level) | ||||
|     { | ||||
|     case NOTICE_LEVEL: // light green
 | ||||
|         Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY; | ||||
|         break; | ||||
|     case ERROR_LEVEL: // light red
 | ||||
|         Color = FOREGROUND_RED | FOREGROUND_INTENSITY; | ||||
|         break; | ||||
|     case WARNING_LEVEL: // light yellow
 | ||||
|         Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; | ||||
|         break; | ||||
|     case INFO_LEVEL: // cyan
 | ||||
|         Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; | ||||
|         break; | ||||
|     case DEBUG_LEVEL: // gray
 | ||||
|         Color = FOREGROUND_INTENSITY; | ||||
|         break; | ||||
|     default: // off-white
 | ||||
|         Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; | ||||
|         break; | ||||
|     } | ||||
|     if (strlen(Text) > 10) | ||||
|     { | ||||
|         // First 10 chars white
 | ||||
|         SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); | ||||
|         WriteConsole(hConsole, Text, 10, &cCharsWritten, NULL); | ||||
|         Text += 10; | ||||
|     } | ||||
|     SetConsoleTextAttribute(hConsole, Color); | ||||
|     WriteConsole(hConsole, Text, (DWORD)strlen(Text), &cCharsWritten, NULL); | ||||
| #else | ||||
| 	char ColorAttr[16] = ""; | ||||
| 	char ResetAttr[16] = ""; | ||||
|     char ColorAttr[16] = ""; | ||||
|     char ResetAttr[16] = ""; | ||||
| 
 | ||||
| 	if (bUseColor) | ||||
| 	{ | ||||
| 		strcpy(ResetAttr, "\033[0m"); | ||||
| 		switch (Level) | ||||
| 		{ | ||||
| 		case NOTICE_LEVEL: // light green
 | ||||
| 			strcpy(ColorAttr, "\033[92m"); | ||||
| 			break; | ||||
| 		case ERROR_LEVEL: // light red
 | ||||
| 			strcpy(ColorAttr, "\033[91m"); | ||||
| 			break; | ||||
| 		case WARNING_LEVEL: // light yellow
 | ||||
| 			strcpy(ColorAttr, "\033[93m"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	fprintf(stderr, "%s%s%s", ColorAttr, Text, ResetAttr); | ||||
|     if (bUseColor) | ||||
|     { | ||||
|         strcpy(ResetAttr, "\033[0m"); | ||||
|         switch (Level) | ||||
|         { | ||||
|         case NOTICE_LEVEL: // light green
 | ||||
|             strcpy(ColorAttr, "\033[92m"); | ||||
|             break; | ||||
|         case ERROR_LEVEL: // light red
 | ||||
|             strcpy(ColorAttr, "\033[91m"); | ||||
|             break; | ||||
|         case WARNING_LEVEL: // light yellow
 | ||||
|             strcpy(ColorAttr, "\033[93m"); | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     fprintf(stderr, "%s%s%s", ColorAttr, Text, ResetAttr); | ||||
| #endif | ||||
| } | ||||
| // Clear console screen
 | ||||
| void ConsoleListener::ClearScreen(bool Cursor) | ||||
| {  | ||||
| #if defined(_WIN32) | ||||
| 	COORD coordScreen = { 0, 0 };  | ||||
| 	DWORD cCharsWritten;  | ||||
| 	CONSOLE_SCREEN_BUFFER_INFO csbi;  | ||||
| 	DWORD dwConSize;  | ||||
|     COORD coordScreen = { 0, 0 };  | ||||
|     DWORD cCharsWritten;  | ||||
|     CONSOLE_SCREEN_BUFFER_INFO csbi;  | ||||
|     DWORD dwConSize;  | ||||
| 
 | ||||
| 	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);  | ||||
|     HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);  | ||||
| 
 | ||||
| 	GetConsoleScreenBufferInfo(hConsole, &csbi);  | ||||
| 	dwConSize = csbi.dwSize.X * csbi.dwSize.Y; | ||||
| 	// Write space to the entire console
 | ||||
| 	FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);  | ||||
| 	GetConsoleScreenBufferInfo(hConsole, &csbi);  | ||||
| 	FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten); | ||||
| 	// Reset cursor
 | ||||
| 	if (Cursor) SetConsoleCursorPosition(hConsole, coordScreen);  | ||||
|     GetConsoleScreenBufferInfo(hConsole, &csbi);  | ||||
|     dwConSize = csbi.dwSize.X * csbi.dwSize.Y; | ||||
|     // Write space to the entire console
 | ||||
|     FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);  | ||||
|     GetConsoleScreenBufferInfo(hConsole, &csbi);  | ||||
|     FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten); | ||||
|     // Reset cursor
 | ||||
|     if (Cursor) SetConsoleCursorPosition(hConsole, coordScreen);  | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,28 +14,28 @@ | |||
| class ConsoleListener : public LogListener | ||||
| { | ||||
| public: | ||||
| 	ConsoleListener(); | ||||
| 	~ConsoleListener(); | ||||
|     ConsoleListener(); | ||||
|     ~ConsoleListener(); | ||||
| 
 | ||||
| 	void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console"); | ||||
| 	void UpdateHandle(); | ||||
| 	void Close(); | ||||
| 	bool IsOpen(); | ||||
| 	void LetterSpace(int Width, int Height); | ||||
| 	void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst); | ||||
| 	void PixelSpace(int Left, int Top, int Width, int Height, bool); | ||||
|     void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console"); | ||||
|     void UpdateHandle(); | ||||
|     void Close(); | ||||
|     bool IsOpen(); | ||||
|     void LetterSpace(int Width, int Height); | ||||
|     void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst); | ||||
|     void PixelSpace(int Left, int Top, int Width, int Height, bool); | ||||
| #ifdef _WIN32 | ||||
| 	COORD GetCoordinates(int BytesRead, int BufferWidth); | ||||
|     COORD GetCoordinates(int BytesRead, int BufferWidth); | ||||
| #endif | ||||
| 	void Log(LogTypes::LOG_LEVELS, const char *Text); | ||||
| 	void ClearScreen(bool Cursor = true); | ||||
|     void Log(LogTypes::LOG_LEVELS, const char *Text); | ||||
|     void ClearScreen(bool Cursor = true); | ||||
| 
 | ||||
| private: | ||||
| #ifdef _WIN32 | ||||
| 	HWND GetHwnd(void); | ||||
| 	HANDLE hConsole; | ||||
|     HWND GetHwnd(void); | ||||
|     HANDLE hConsole; | ||||
| #endif | ||||
| 	bool bUseColor; | ||||
|     bool bUseColor; | ||||
| }; | ||||
| 
 | ||||
| #endif  // _CONSOLELISTENER_H
 | ||||
|  |  | |||
|  | @ -11,69 +11,69 @@ | |||
| 
 | ||||
| enum CPUVendor | ||||
| { | ||||
| 	VENDOR_INTEL = 0, | ||||
| 	VENDOR_AMD = 1, | ||||
| 	VENDOR_ARM = 2, | ||||
| 	VENDOR_OTHER = 3, | ||||
|     VENDOR_INTEL = 0, | ||||
|     VENDOR_AMD = 1, | ||||
|     VENDOR_ARM = 2, | ||||
|     VENDOR_OTHER = 3, | ||||
| }; | ||||
| 
 | ||||
| struct CPUInfo | ||||
| { | ||||
| 	CPUVendor vendor; | ||||
|     CPUVendor vendor; | ||||
| 
 | ||||
| 	char cpu_string[0x21]; | ||||
| 	char brand_string[0x41]; | ||||
| 	bool OS64bit; | ||||
| 	bool CPU64bit; | ||||
| 	bool Mode64bit; | ||||
|     char cpu_string[0x21]; | ||||
|     char brand_string[0x41]; | ||||
|     bool OS64bit; | ||||
|     bool CPU64bit; | ||||
|     bool Mode64bit; | ||||
| 
 | ||||
| 	bool HTT; | ||||
| 	int num_cores; | ||||
| 	int logical_cpu_count; | ||||
|     bool HTT; | ||||
|     int num_cores; | ||||
|     int logical_cpu_count; | ||||
| 
 | ||||
| 	bool bSSE; | ||||
| 	bool bSSE2; | ||||
| 	bool bSSE3; | ||||
| 	bool bSSSE3; | ||||
| 	bool bPOPCNT; | ||||
| 	bool bSSE4_1; | ||||
| 	bool bSSE4_2; | ||||
| 	bool bLZCNT; | ||||
| 	bool bSSE4A; | ||||
| 	bool bAVX; | ||||
| 	bool bAES; | ||||
| 	bool bLAHFSAHF64; | ||||
| 	bool bLongMode; | ||||
|     bool bSSE; | ||||
|     bool bSSE2; | ||||
|     bool bSSE3; | ||||
|     bool bSSSE3; | ||||
|     bool bPOPCNT; | ||||
|     bool bSSE4_1; | ||||
|     bool bSSE4_2; | ||||
|     bool bLZCNT; | ||||
|     bool bSSE4A; | ||||
|     bool bAVX; | ||||
|     bool bAES; | ||||
|     bool bLAHFSAHF64; | ||||
|     bool bLongMode; | ||||
| 
 | ||||
| 	// ARM specific CPUInfo
 | ||||
| 	bool bSwp; | ||||
| 	bool bHalf; | ||||
| 	bool bThumb; | ||||
| 	bool bFastMult; | ||||
| 	bool bVFP; | ||||
| 	bool bEDSP; | ||||
| 	bool bThumbEE; | ||||
| 	bool bNEON; | ||||
| 	bool bVFPv3; | ||||
| 	bool bTLS; | ||||
| 	bool bVFPv4; | ||||
| 	bool bIDIVa; | ||||
| 	bool bIDIVt; | ||||
| 	bool bArmV7;  // enable MOVT, MOVW etc
 | ||||
|     // ARM specific CPUInfo
 | ||||
|     bool bSwp; | ||||
|     bool bHalf; | ||||
|     bool bThumb; | ||||
|     bool bFastMult; | ||||
|     bool bVFP; | ||||
|     bool bEDSP; | ||||
|     bool bThumbEE; | ||||
|     bool bNEON; | ||||
|     bool bVFPv3; | ||||
|     bool bTLS; | ||||
|     bool bVFPv4; | ||||
|     bool bIDIVa; | ||||
|     bool bIDIVt; | ||||
|     bool bArmV7;  // enable MOVT, MOVW etc
 | ||||
| 
 | ||||
| 	// ARMv8 specific
 | ||||
| 	bool bFP; | ||||
| 	bool bASIMD; | ||||
|     // ARMv8 specific
 | ||||
|     bool bFP; | ||||
|     bool bASIMD; | ||||
| 
 | ||||
| 	// Call Detect()
 | ||||
| 	explicit CPUInfo(); | ||||
|     // Call Detect()
 | ||||
|     explicit CPUInfo(); | ||||
| 
 | ||||
| 	// Turn the cpu info into a string we can show
 | ||||
| 	std::string Summarize(); | ||||
|     // Turn the cpu info into a string we can show
 | ||||
|     std::string Summarize(); | ||||
| 
 | ||||
| private: | ||||
| 	// Detects the various cpu features
 | ||||
| 	void Detect(); | ||||
|     // Detects the various cpu features
 | ||||
|     void Detect(); | ||||
| }; | ||||
| 
 | ||||
| extern CPUInfo cpu_info; | ||||
|  |  | |||
|  | @ -7,33 +7,33 @@ | |||
| class DebugInterface | ||||
| { | ||||
| protected: | ||||
| 	virtual ~DebugInterface() {} | ||||
|     virtual ~DebugInterface() {} | ||||
| 
 | ||||
| public: | ||||
| 	virtual void disasm(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} | ||||
| 	virtual void getRawMemoryString(int /*memory*/, unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} | ||||
| 	virtual int getInstructionSize(int /*instruction*/) {return 1;} | ||||
| 	virtual bool isAlive() {return true;} | ||||
| 	virtual bool isBreakpoint(unsigned int /*address*/) {return false;} | ||||
| 	virtual void setBreakpoint(unsigned int /*address*/){} | ||||
| 	virtual void clearBreakpoint(unsigned int /*address*/){} | ||||
| 	virtual void clearAllBreakpoints() {} | ||||
| 	virtual void toggleBreakpoint(unsigned int /*address*/){} | ||||
| 	virtual bool isMemCheck(unsigned int /*address*/) {return false;} | ||||
| 	virtual void toggleMemCheck(unsigned int /*address*/){} | ||||
| 	virtual unsigned int readMemory(unsigned int /*address*/){return 0;} | ||||
| 	virtual void writeExtraMemory(int /*memory*/, unsigned int /*value*/, unsigned int /*address*/) {} | ||||
| 	virtual unsigned int readExtraMemory(int /*memory*/, unsigned int /*address*/){return 0;} | ||||
| 	virtual unsigned int readInstruction(unsigned int /*address*/){return 0;} | ||||
| 	virtual unsigned int getPC() {return 0;} | ||||
| 	virtual void setPC(unsigned int /*address*/) {} | ||||
| 	virtual void step() {} | ||||
| 	virtual void runToBreakpoint() {} | ||||
| 	virtual void breakNow() {} | ||||
| 	virtual void insertBLR(unsigned int /*address*/, unsigned int /*value*/) {} | ||||
| 	virtual void showJitResults(unsigned int /*address*/) {}; | ||||
| 	virtual int getColor(unsigned int /*address*/){return 0xFFFFFFFF;} | ||||
| 	virtual std::string getDescription(unsigned int /*address*/) = 0; | ||||
|     virtual void disasm(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} | ||||
|     virtual void getRawMemoryString(int /*memory*/, unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} | ||||
|     virtual int getInstructionSize(int /*instruction*/) {return 1;} | ||||
|     virtual bool isAlive() {return true;} | ||||
|     virtual bool isBreakpoint(unsigned int /*address*/) {return false;} | ||||
|     virtual void setBreakpoint(unsigned int /*address*/){} | ||||
|     virtual void clearBreakpoint(unsigned int /*address*/){} | ||||
|     virtual void clearAllBreakpoints() {} | ||||
|     virtual void toggleBreakpoint(unsigned int /*address*/){} | ||||
|     virtual bool isMemCheck(unsigned int /*address*/) {return false;} | ||||
|     virtual void toggleMemCheck(unsigned int /*address*/){} | ||||
|     virtual unsigned int readMemory(unsigned int /*address*/){return 0;} | ||||
|     virtual void writeExtraMemory(int /*memory*/, unsigned int /*value*/, unsigned int /*address*/) {} | ||||
|     virtual unsigned int readExtraMemory(int /*memory*/, unsigned int /*address*/){return 0;} | ||||
|     virtual unsigned int readInstruction(unsigned int /*address*/){return 0;} | ||||
|     virtual unsigned int getPC() {return 0;} | ||||
|     virtual void setPC(unsigned int /*address*/) {} | ||||
|     virtual void step() {} | ||||
|     virtual void runToBreakpoint() {} | ||||
|     virtual void breakNow() {} | ||||
|     virtual void insertBLR(unsigned int /*address*/, unsigned int /*value*/) {} | ||||
|     virtual void showJitResults(unsigned int /*address*/) {}; | ||||
|     virtual int getColor(unsigned int /*address*/){return 0xFFFFFFFF;} | ||||
|     virtual std::string getDescription(unsigned int /*address*/) = 0; | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -48,8 +48,8 @@ public: | |||
|     /// Swap buffers to display the next frame
 | ||||
|     virtual void SwapBuffers() = 0; | ||||
| 
 | ||||
| 	/// Polls window events
 | ||||
| 	virtual void PollEvents() = 0; | ||||
|     /// Polls window events
 | ||||
|     virtual void PollEvents() = 0; | ||||
| 
 | ||||
|     /// Makes the graphics context current for the caller thread
 | ||||
|     virtual void MakeCurrent() = 0; | ||||
|  |  | |||
|  | @ -30,18 +30,18 @@ using namespace std; | |||
| void PCSTR2LPTSTR( PCSTR lpszIn, LPTSTR lpszOut ) | ||||
| { | ||||
| #if defined(UNICODE)||defined(_UNICODE) | ||||
| 	ULONG index = 0;  | ||||
| 	PCSTR lpAct = lpszIn; | ||||
|     ULONG index = 0;  | ||||
|     PCSTR lpAct = lpszIn; | ||||
| 
 | ||||
| 	for( ; ; lpAct++ ) | ||||
| 	{ | ||||
| 		lpszOut[index++] = (TCHAR)(*lpAct); | ||||
| 		if ( *lpAct == 0 ) | ||||
| 			break; | ||||
| 	}  | ||||
|     for( ; ; lpAct++ ) | ||||
|     { | ||||
|         lpszOut[index++] = (TCHAR)(*lpAct); | ||||
|         if ( *lpAct == 0 ) | ||||
|             break; | ||||
|     }  | ||||
| #else | ||||
| 	// This is trivial :)
 | ||||
| 	strcpy( lpszOut, lpszIn ); | ||||
|     // This is trivial :)
 | ||||
|     strcpy( lpszOut, lpszIn ); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  | @ -50,184 +50,184 @@ void PCSTR2LPTSTR( PCSTR lpszIn, LPTSTR lpszOut ) | |||
| // Note: There is no size check for lpszSymbolPath!
 | ||||
| static void InitSymbolPath( PSTR lpszSymbolPath, PCSTR lpszIniPath ) | ||||
| { | ||||
| 	CHAR lpszPath[BUFFERSIZE]; | ||||
|     CHAR lpszPath[BUFFERSIZE]; | ||||
| 
 | ||||
| 	// Creating the default path
 | ||||
| 	// ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%SYSTEMROOT%;%SYSTEMROOT%\System32;"
 | ||||
| 	strcpy( lpszSymbolPath, "." ); | ||||
|     // Creating the default path
 | ||||
|     // ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%SYSTEMROOT%;%SYSTEMROOT%\System32;"
 | ||||
|     strcpy( lpszSymbolPath, "." ); | ||||
| 
 | ||||
| 	// environment variable _NT_SYMBOL_PATH
 | ||||
| 	if ( GetEnvironmentVariableA( "_NT_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) | ||||
| 	{ | ||||
| 		strcat( lpszSymbolPath, ";" ); | ||||
| 		strcat( lpszSymbolPath, lpszPath ); | ||||
| 	} | ||||
|     // environment variable _NT_SYMBOL_PATH
 | ||||
|     if ( GetEnvironmentVariableA( "_NT_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) | ||||
|     { | ||||
|         strcat( lpszSymbolPath, ";" ); | ||||
|         strcat( lpszSymbolPath, lpszPath ); | ||||
|     } | ||||
| 
 | ||||
| 	// environment variable _NT_ALTERNATE_SYMBOL_PATH
 | ||||
| 	if ( GetEnvironmentVariableA( "_NT_ALTERNATE_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) | ||||
| 	{ | ||||
| 		strcat( lpszSymbolPath, ";" ); | ||||
| 		strcat( lpszSymbolPath, lpszPath ); | ||||
| 	} | ||||
|     // environment variable _NT_ALTERNATE_SYMBOL_PATH
 | ||||
|     if ( GetEnvironmentVariableA( "_NT_ALTERNATE_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) | ||||
|     { | ||||
|         strcat( lpszSymbolPath, ";" ); | ||||
|         strcat( lpszSymbolPath, lpszPath ); | ||||
|     } | ||||
| 
 | ||||
| 	// environment variable SYSTEMROOT
 | ||||
| 	if ( GetEnvironmentVariableA( "SYSTEMROOT", lpszPath, BUFFERSIZE ) ) | ||||
| 	{ | ||||
| 		strcat( lpszSymbolPath, ";" ); | ||||
| 		strcat( lpszSymbolPath, lpszPath ); | ||||
| 		strcat( lpszSymbolPath, ";" ); | ||||
|     // environment variable SYSTEMROOT
 | ||||
|     if ( GetEnvironmentVariableA( "SYSTEMROOT", lpszPath, BUFFERSIZE ) ) | ||||
|     { | ||||
|         strcat( lpszSymbolPath, ";" ); | ||||
|         strcat( lpszSymbolPath, lpszPath ); | ||||
|         strcat( lpszSymbolPath, ";" ); | ||||
| 
 | ||||
| 		// SYSTEMROOT\System32
 | ||||
| 		strcat( lpszSymbolPath, lpszPath ); | ||||
| 		strcat( lpszSymbolPath, "\\System32" ); | ||||
| 	} | ||||
|         // SYSTEMROOT\System32
 | ||||
|         strcat( lpszSymbolPath, lpszPath ); | ||||
|         strcat( lpszSymbolPath, "\\System32" ); | ||||
|     } | ||||
| 
 | ||||
| 	// Add user defined path
 | ||||
| 	if ( lpszIniPath != NULL ) | ||||
| 		if ( lpszIniPath[0] != '\0' ) | ||||
| 		{ | ||||
| 			strcat( lpszSymbolPath, ";" ); | ||||
| 			strcat( lpszSymbolPath, lpszIniPath ); | ||||
| 		} | ||||
|     // Add user defined path
 | ||||
|     if ( lpszIniPath != NULL ) | ||||
|         if ( lpszIniPath[0] != '\0' ) | ||||
|         { | ||||
|             strcat( lpszSymbolPath, ";" ); | ||||
|             strcat( lpszSymbolPath, lpszIniPath ); | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| // Uninitialize the loaded symbol files
 | ||||
| BOOL UninitSymInfo() { | ||||
| 	return SymCleanup( GetCurrentProcess() ); | ||||
|     return SymCleanup( GetCurrentProcess() ); | ||||
| } | ||||
| 
 | ||||
| // Initializes the symbol files
 | ||||
| BOOL InitSymInfo( PCSTR lpszInitialSymbolPath ) | ||||
| { | ||||
| 	CHAR     lpszSymbolPath[BUFFERSIZE]; | ||||
| 	DWORD    symOptions = SymGetOptions(); | ||||
|     CHAR     lpszSymbolPath[BUFFERSIZE]; | ||||
|     DWORD    symOptions = SymGetOptions(); | ||||
| 
 | ||||
| 	symOptions |= SYMOPT_LOAD_LINES;  | ||||
| 	symOptions &= ~SYMOPT_UNDNAME; | ||||
| 	SymSetOptions( symOptions ); | ||||
| 	InitSymbolPath( lpszSymbolPath, lpszInitialSymbolPath ); | ||||
|     symOptions |= SYMOPT_LOAD_LINES;  | ||||
|     symOptions &= ~SYMOPT_UNDNAME; | ||||
|     SymSetOptions( symOptions ); | ||||
|     InitSymbolPath( lpszSymbolPath, lpszInitialSymbolPath ); | ||||
| 
 | ||||
| 	return SymInitialize( GetCurrentProcess(), lpszSymbolPath, TRUE); | ||||
|     return SymInitialize( GetCurrentProcess(), lpszSymbolPath, TRUE); | ||||
| } | ||||
| 
 | ||||
| // Get the module name from a given address
 | ||||
| static BOOL GetModuleNameFromAddress( UINT address, LPTSTR lpszModule ) | ||||
| { | ||||
| 	BOOL              ret = FALSE; | ||||
| 	IMAGEHLP_MODULE   moduleInfo; | ||||
|     BOOL              ret = FALSE; | ||||
|     IMAGEHLP_MODULE   moduleInfo; | ||||
| 
 | ||||
| 	::ZeroMemory( &moduleInfo, sizeof(moduleInfo) ); | ||||
| 	moduleInfo.SizeOfStruct = sizeof(moduleInfo); | ||||
|     ::ZeroMemory( &moduleInfo, sizeof(moduleInfo) ); | ||||
|     moduleInfo.SizeOfStruct = sizeof(moduleInfo); | ||||
| 
 | ||||
| 	if ( SymGetModuleInfo( GetCurrentProcess(), (DWORD)address, &moduleInfo ) ) | ||||
| 	{ | ||||
| 		// Got it!
 | ||||
| 		PCSTR2LPTSTR( moduleInfo.ModuleName, lpszModule ); | ||||
| 		ret = TRUE; | ||||
| 	} | ||||
| 	else | ||||
| 		// Not found :(
 | ||||
| 		_tcscpy( lpszModule, _T("?") ); | ||||
|     if ( SymGetModuleInfo( GetCurrentProcess(), (DWORD)address, &moduleInfo ) ) | ||||
|     { | ||||
|         // Got it!
 | ||||
|         PCSTR2LPTSTR( moduleInfo.ModuleName, lpszModule ); | ||||
|         ret = TRUE; | ||||
|     } | ||||
|     else | ||||
|         // Not found :(
 | ||||
|         _tcscpy( lpszModule, _T("?") ); | ||||
| 
 | ||||
| 	return ret; | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| // Get function prototype and parameter info from ip address and stack address
 | ||||
| static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, LPTSTR lpszSymbol ) | ||||
| { | ||||
| 	BOOL              ret = FALSE; | ||||
| 	DWORD             dwSymSize = 10000; | ||||
| 	TCHAR             lpszUnDSymbol[BUFFERSIZE]=_T("?"); | ||||
| 	CHAR              lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?"; | ||||
| 	LPTSTR            lpszParamSep = NULL; | ||||
| 	LPTSTR            lpszParsed = lpszUnDSymbol; | ||||
| 	PIMAGEHLP_SYMBOL  pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize ); | ||||
|     BOOL              ret = FALSE; | ||||
|     DWORD             dwSymSize = 10000; | ||||
|     TCHAR             lpszUnDSymbol[BUFFERSIZE]=_T("?"); | ||||
|     CHAR              lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?"; | ||||
|     LPTSTR            lpszParamSep = NULL; | ||||
|     LPTSTR            lpszParsed = lpszUnDSymbol; | ||||
|     PIMAGEHLP_SYMBOL  pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize ); | ||||
| 
 | ||||
| 	::ZeroMemory( pSym, dwSymSize ); | ||||
| 	pSym->SizeOfStruct = dwSymSize; | ||||
| 	pSym->MaxNameLength = dwSymSize - sizeof(IMAGEHLP_SYMBOL); | ||||
|     ::ZeroMemory( pSym, dwSymSize ); | ||||
|     pSym->SizeOfStruct = dwSymSize; | ||||
|     pSym->MaxNameLength = dwSymSize - sizeof(IMAGEHLP_SYMBOL); | ||||
| 
 | ||||
| 	// Set the default to unknown
 | ||||
| 	_tcscpy( lpszSymbol, _T("?") ); | ||||
|     // Set the default to unknown
 | ||||
|     _tcscpy( lpszSymbol, _T("?") ); | ||||
| 
 | ||||
| 	// Get symbol info for IP
 | ||||
|     // Get symbol info for IP
 | ||||
| #ifndef _M_X64 | ||||
| 	DWORD             dwDisp = 0; | ||||
| 	if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, &dwDisp, pSym ) ) | ||||
|     DWORD             dwDisp = 0; | ||||
|     if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, &dwDisp, pSym ) ) | ||||
| #else  | ||||
| 	//makes it compile but hell im not sure if this works...
 | ||||
| 	DWORD64           dwDisp = 0; | ||||
| 	if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) ) | ||||
|     //makes it compile but hell im not sure if this works...
 | ||||
|     DWORD64           dwDisp = 0; | ||||
|     if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) ) | ||||
| #endif | ||||
| 	{ | ||||
| 		// Make the symbol readable for humans
 | ||||
| 		UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE,  | ||||
| 			UNDNAME_COMPLETE |  | ||||
| 			UNDNAME_NO_THISTYPE | | ||||
| 			UNDNAME_NO_SPECIAL_SYMS | | ||||
| 			UNDNAME_NO_MEMBER_TYPE | | ||||
| 			UNDNAME_NO_MS_KEYWORDS | | ||||
| 			UNDNAME_NO_ACCESS_SPECIFIERS ); | ||||
|     { | ||||
|         // Make the symbol readable for humans
 | ||||
|         UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE,  | ||||
|             UNDNAME_COMPLETE |  | ||||
|             UNDNAME_NO_THISTYPE | | ||||
|             UNDNAME_NO_SPECIAL_SYMS | | ||||
|             UNDNAME_NO_MEMBER_TYPE | | ||||
|             UNDNAME_NO_MS_KEYWORDS | | ||||
|             UNDNAME_NO_ACCESS_SPECIFIERS ); | ||||
| 
 | ||||
| 		// Symbol information is ANSI string
 | ||||
| 		PCSTR2LPTSTR( lpszNonUnicodeUnDSymbol, lpszUnDSymbol ); | ||||
|         // Symbol information is ANSI string
 | ||||
|         PCSTR2LPTSTR( lpszNonUnicodeUnDSymbol, lpszUnDSymbol ); | ||||
| 
 | ||||
| 		// I am just smarter than the symbol file :)
 | ||||
| 		if ( _tcscmp(lpszUnDSymbol, _T("_WinMain@16")) == 0 ) | ||||
| 			_tcscpy(lpszUnDSymbol, _T("WinMain(HINSTANCE,HINSTANCE,LPCTSTR,int)")); | ||||
| 		else | ||||
| 			if ( _tcscmp(lpszUnDSymbol, _T("_main")) == 0 ) | ||||
| 				_tcscpy(lpszUnDSymbol, _T("main(int,TCHAR * *)")); | ||||
| 			else | ||||
| 				if ( _tcscmp(lpszUnDSymbol, _T("_mainCRTStartup")) == 0 ) | ||||
| 					_tcscpy(lpszUnDSymbol, _T("mainCRTStartup()")); | ||||
| 				else | ||||
| 					if ( _tcscmp(lpszUnDSymbol, _T("_wmain")) == 0 ) | ||||
| 						_tcscpy(lpszUnDSymbol, _T("wmain(int,TCHAR * *,TCHAR * *)")); | ||||
| 					else | ||||
| 						if ( _tcscmp(lpszUnDSymbol, _T("_wmainCRTStartup")) == 0 ) | ||||
| 							_tcscpy(lpszUnDSymbol, _T("wmainCRTStartup()")); | ||||
|         // I am just smarter than the symbol file :)
 | ||||
|         if ( _tcscmp(lpszUnDSymbol, _T("_WinMain@16")) == 0 ) | ||||
|             _tcscpy(lpszUnDSymbol, _T("WinMain(HINSTANCE,HINSTANCE,LPCTSTR,int)")); | ||||
|         else | ||||
|             if ( _tcscmp(lpszUnDSymbol, _T("_main")) == 0 ) | ||||
|                 _tcscpy(lpszUnDSymbol, _T("main(int,TCHAR * *)")); | ||||
|             else | ||||
|                 if ( _tcscmp(lpszUnDSymbol, _T("_mainCRTStartup")) == 0 ) | ||||
|                     _tcscpy(lpszUnDSymbol, _T("mainCRTStartup()")); | ||||
|                 else | ||||
|                     if ( _tcscmp(lpszUnDSymbol, _T("_wmain")) == 0 ) | ||||
|                         _tcscpy(lpszUnDSymbol, _T("wmain(int,TCHAR * *,TCHAR * *)")); | ||||
|                     else | ||||
|                         if ( _tcscmp(lpszUnDSymbol, _T("_wmainCRTStartup")) == 0 ) | ||||
|                             _tcscpy(lpszUnDSymbol, _T("wmainCRTStartup()")); | ||||
| 
 | ||||
| 		lpszSymbol[0] = _T('\0'); | ||||
|         lpszSymbol[0] = _T('\0'); | ||||
| 
 | ||||
| 		// Let's go through the stack, and modify the function prototype, and insert the actual
 | ||||
| 		// parameter values from the stack
 | ||||
| 		if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == NULL && _tcsstr( lpszUnDSymbol, _T("()") ) == NULL) | ||||
| 		{ | ||||
| 			ULONG index = 0; | ||||
| 			for( ; ; index++ ) | ||||
| 			{ | ||||
| 				lpszParamSep = _tcschr( lpszParsed, _T(',') ); | ||||
| 				if ( lpszParamSep == NULL ) | ||||
| 					break; | ||||
|         // Let's go through the stack, and modify the function prototype, and insert the actual
 | ||||
|         // parameter values from the stack
 | ||||
|         if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == NULL && _tcsstr( lpszUnDSymbol, _T("()") ) == NULL) | ||||
|         { | ||||
|             ULONG index = 0; | ||||
|             for( ; ; index++ ) | ||||
|             { | ||||
|                 lpszParamSep = _tcschr( lpszParsed, _T(',') ); | ||||
|                 if ( lpszParamSep == NULL ) | ||||
|                     break; | ||||
| 
 | ||||
| 				*lpszParamSep = _T('\0'); | ||||
|                 *lpszParamSep = _T('\0'); | ||||
| 
 | ||||
| 				_tcscat( lpszSymbol, lpszParsed ); | ||||
| 				_stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X,"), *((ULONG*)(stackAddress) + 2 + index) ); | ||||
|                 _tcscat( lpszSymbol, lpszParsed ); | ||||
|                 _stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X,"), *((ULONG*)(stackAddress) + 2 + index) ); | ||||
| 
 | ||||
| 				lpszParsed = lpszParamSep + 1; | ||||
| 			} | ||||
|                 lpszParsed = lpszParamSep + 1; | ||||
|             } | ||||
| 
 | ||||
| 			lpszParamSep = _tcschr( lpszParsed, _T(')') ); | ||||
| 			if ( lpszParamSep != NULL ) | ||||
| 			{ | ||||
| 				*lpszParamSep = _T('\0'); | ||||
|             lpszParamSep = _tcschr( lpszParsed, _T(')') ); | ||||
|             if ( lpszParamSep != NULL ) | ||||
|             { | ||||
|                 *lpszParamSep = _T('\0'); | ||||
| 
 | ||||
| 				_tcscat( lpszSymbol, lpszParsed ); | ||||
| 				_stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X)"), *((ULONG*)(stackAddress) + 2 + index) ); | ||||
|                 _tcscat( lpszSymbol, lpszParsed ); | ||||
|                 _stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X)"), *((ULONG*)(stackAddress) + 2 + index) ); | ||||
| 
 | ||||
| 				lpszParsed = lpszParamSep + 1; | ||||
| 			} | ||||
| 		} | ||||
|                 lpszParsed = lpszParamSep + 1; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 		_tcscat( lpszSymbol, lpszParsed ); | ||||
|         _tcscat( lpszSymbol, lpszParsed ); | ||||
| 
 | ||||
| 		ret = TRUE; | ||||
| 	}  | ||||
| 	GlobalFree( pSym ); | ||||
|         ret = TRUE; | ||||
|     }  | ||||
|     GlobalFree( pSym ); | ||||
| 
 | ||||
| 	return ret; | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| // Get source file name and line number from IP address
 | ||||
|  | @ -236,198 +236,198 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L | |||
| //                       "address"
 | ||||
| static BOOL GetSourceInfoFromAddress( UINT address, LPTSTR lpszSourceInfo ) | ||||
| { | ||||
| 	BOOL           ret = FALSE; | ||||
| 	IMAGEHLP_LINE  lineInfo; | ||||
| 	DWORD          dwDisp; | ||||
| 	TCHAR          lpszFileName[BUFFERSIZE] = _T(""); | ||||
| 	TCHAR          lpModuleInfo[BUFFERSIZE] = _T(""); | ||||
|     BOOL           ret = FALSE; | ||||
|     IMAGEHLP_LINE  lineInfo; | ||||
|     DWORD          dwDisp; | ||||
|     TCHAR          lpszFileName[BUFFERSIZE] = _T(""); | ||||
|     TCHAR          lpModuleInfo[BUFFERSIZE] = _T(""); | ||||
| 
 | ||||
| 	_tcscpy( lpszSourceInfo, _T("?(?)") ); | ||||
|     _tcscpy( lpszSourceInfo, _T("?(?)") ); | ||||
| 
 | ||||
| 	::ZeroMemory( &lineInfo, sizeof( lineInfo ) ); | ||||
| 	lineInfo.SizeOfStruct = sizeof( lineInfo ); | ||||
|     ::ZeroMemory( &lineInfo, sizeof( lineInfo ) ); | ||||
|     lineInfo.SizeOfStruct = sizeof( lineInfo ); | ||||
| 
 | ||||
| 	if ( SymGetLineFromAddr( GetCurrentProcess(), address, &dwDisp, &lineInfo ) ) | ||||
| 	{ | ||||
| 		// Got it. Let's use "sourcefile(linenumber)" format
 | ||||
| 		PCSTR2LPTSTR( lineInfo.FileName, lpszFileName ); | ||||
| 		TCHAR fname[_MAX_FNAME]; | ||||
| 		TCHAR ext[_MAX_EXT]; | ||||
| 		_tsplitpath(lpszFileName, NULL, NULL, fname, ext); | ||||
| 		_stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber ); | ||||
| 		ret = TRUE; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		// There is no source file information. :(
 | ||||
| 		// Let's use the "modulename!address" format
 | ||||
| 		GetModuleNameFromAddress( address, lpModuleInfo ); | ||||
|     if ( SymGetLineFromAddr( GetCurrentProcess(), address, &dwDisp, &lineInfo ) ) | ||||
|     { | ||||
|         // Got it. Let's use "sourcefile(linenumber)" format
 | ||||
|         PCSTR2LPTSTR( lineInfo.FileName, lpszFileName ); | ||||
|         TCHAR fname[_MAX_FNAME]; | ||||
|         TCHAR ext[_MAX_EXT]; | ||||
|         _tsplitpath(lpszFileName, NULL, NULL, fname, ext); | ||||
|         _stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber ); | ||||
|         ret = TRUE; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // There is no source file information. :(
 | ||||
|         // Let's use the "modulename!address" format
 | ||||
|         GetModuleNameFromAddress( address, lpModuleInfo ); | ||||
| 
 | ||||
| 		if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0')) | ||||
| 			// There is no modulename information. :((
 | ||||
| 			// Let's use the "address" format
 | ||||
| 			_stprintf( lpszSourceInfo, _T("0x%08X"), address ); | ||||
| 		else | ||||
| 			_stprintf( lpszSourceInfo, _T("%s!0x%08X"), lpModuleInfo, address ); | ||||
|         if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0')) | ||||
|             // There is no modulename information. :((
 | ||||
|             // Let's use the "address" format
 | ||||
|             _stprintf( lpszSourceInfo, _T("0x%08X"), address ); | ||||
|         else | ||||
|             _stprintf( lpszSourceInfo, _T("%s!0x%08X"), lpModuleInfo, address ); | ||||
| 
 | ||||
| 		ret = FALSE; | ||||
| 	} | ||||
|         ret = FALSE; | ||||
|     } | ||||
| 
 | ||||
| 	return ret; | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| void PrintFunctionAndSourceInfo(FILE* file, const STACKFRAME& callstack) | ||||
| { | ||||
| 	TCHAR symInfo[BUFFERSIZE] = _T("?"); | ||||
| 	TCHAR srcInfo[BUFFERSIZE] = _T("?"); | ||||
|     TCHAR symInfo[BUFFERSIZE] = _T("?"); | ||||
|     TCHAR srcInfo[BUFFERSIZE] = _T("?"); | ||||
| 
 | ||||
| 	GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo); | ||||
| 	GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo); | ||||
| 	etfprint(file, "     " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n"); | ||||
|     GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo); | ||||
|     GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo); | ||||
|     etfprint(file, "     " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n"); | ||||
| } | ||||
| 
 | ||||
| void StackTrace( HANDLE hThread, const char* lpszMessage, FILE *file ) | ||||
| { | ||||
| 	STACKFRAME     callStack; | ||||
| 	BOOL           bResult; | ||||
| 	CONTEXT        context; | ||||
| 	HANDLE         hProcess = GetCurrentProcess(); | ||||
|     STACKFRAME     callStack; | ||||
|     BOOL           bResult; | ||||
|     CONTEXT        context; | ||||
|     HANDLE         hProcess = GetCurrentProcess(); | ||||
| 
 | ||||
| 	// If it's not this thread, let's suspend it, and resume it at the end
 | ||||
| 	if ( hThread != GetCurrentThread() ) | ||||
| 		if ( SuspendThread( hThread ) == -1 ) | ||||
| 		{ | ||||
| 			// whaaat ?!
 | ||||
| 			etfprint(file, "Call stack info failed\n"); | ||||
| 			return; | ||||
| 		} | ||||
|     // If it's not this thread, let's suspend it, and resume it at the end
 | ||||
|     if ( hThread != GetCurrentThread() ) | ||||
|         if ( SuspendThread( hThread ) == -1 ) | ||||
|         { | ||||
|             // whaaat ?!
 | ||||
|             etfprint(file, "Call stack info failed\n"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
| 		::ZeroMemory( &context, sizeof(context) ); | ||||
| 		context.ContextFlags = CONTEXT_FULL; | ||||
|         ::ZeroMemory( &context, sizeof(context) ); | ||||
|         context.ContextFlags = CONTEXT_FULL; | ||||
| 
 | ||||
| 		if ( !GetThreadContext( hThread, &context ) ) | ||||
| 		{ | ||||
| 			etfprint(file, "Call stack info failed\n"); | ||||
| 			return; | ||||
| 		} | ||||
|         if ( !GetThreadContext( hThread, &context ) ) | ||||
|         { | ||||
|             etfprint(file, "Call stack info failed\n"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
| 		::ZeroMemory( &callStack, sizeof(callStack) ); | ||||
|         ::ZeroMemory( &callStack, sizeof(callStack) ); | ||||
| #ifndef _M_X64 | ||||
| 		callStack.AddrPC.Offset    = context.Eip; | ||||
| 		callStack.AddrStack.Offset = context.Esp; | ||||
| 		callStack.AddrFrame.Offset = context.Ebp; | ||||
|         callStack.AddrPC.Offset    = context.Eip; | ||||
|         callStack.AddrStack.Offset = context.Esp; | ||||
|         callStack.AddrFrame.Offset = context.Ebp; | ||||
| #else | ||||
| 		callStack.AddrPC.Offset    = context.Rip; | ||||
| 		callStack.AddrStack.Offset = context.Rsp; | ||||
| 		callStack.AddrFrame.Offset = context.Rbp; | ||||
|         callStack.AddrPC.Offset    = context.Rip; | ||||
|         callStack.AddrStack.Offset = context.Rsp; | ||||
|         callStack.AddrFrame.Offset = context.Rbp; | ||||
| #endif | ||||
| 		callStack.AddrPC.Mode      = AddrModeFlat; | ||||
| 		callStack.AddrStack.Mode   = AddrModeFlat; | ||||
| 		callStack.AddrFrame.Mode   = AddrModeFlat; | ||||
|         callStack.AddrPC.Mode      = AddrModeFlat; | ||||
|         callStack.AddrStack.Mode   = AddrModeFlat; | ||||
|         callStack.AddrFrame.Mode   = AddrModeFlat; | ||||
| 
 | ||||
| 		etfprint(file, "Call stack info: \n"); | ||||
| 		etfprint(file, lpszMessage); | ||||
|         etfprint(file, "Call stack info: \n"); | ||||
|         etfprint(file, lpszMessage); | ||||
| 
 | ||||
| 		PrintFunctionAndSourceInfo(file, callStack); | ||||
|         PrintFunctionAndSourceInfo(file, callStack); | ||||
| 
 | ||||
| 		for( ULONG index = 0; ; index++ )  | ||||
| 		{ | ||||
| 			bResult = StackWalk( | ||||
| 				IMAGE_FILE_MACHINE_I386, | ||||
| 				hProcess, | ||||
| 				hThread, | ||||
| 				&callStack, | ||||
| 				NULL,  | ||||
| 				NULL, | ||||
| 				SymFunctionTableAccess, | ||||
| 				SymGetModuleBase, | ||||
| 				NULL); | ||||
|         for( ULONG index = 0; ; index++ )  | ||||
|         { | ||||
|             bResult = StackWalk( | ||||
|                 IMAGE_FILE_MACHINE_I386, | ||||
|                 hProcess, | ||||
|                 hThread, | ||||
|                 &callStack, | ||||
|                 NULL,  | ||||
|                 NULL, | ||||
|                 SymFunctionTableAccess, | ||||
|                 SymGetModuleBase, | ||||
|                 NULL); | ||||
| 
 | ||||
| 			if ( index == 0 ) | ||||
| 				continue; | ||||
|             if ( index == 0 ) | ||||
|                 continue; | ||||
| 
 | ||||
| 			if( !bResult || callStack.AddrFrame.Offset == 0 )  | ||||
| 				break; | ||||
|             if( !bResult || callStack.AddrFrame.Offset == 0 )  | ||||
|                 break; | ||||
| 
 | ||||
| 			PrintFunctionAndSourceInfo(file, callStack); | ||||
|             PrintFunctionAndSourceInfo(file, callStack); | ||||
| 
 | ||||
| 		} | ||||
|         } | ||||
| 
 | ||||
| 		if ( hThread != GetCurrentThread() ) | ||||
| 			ResumeThread( hThread ); | ||||
|         if ( hThread != GetCurrentThread() ) | ||||
|             ResumeThread( hThread ); | ||||
| } | ||||
| 
 | ||||
| void StackTrace(HANDLE hThread, const char* lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp ) | ||||
| { | ||||
| 	STACKFRAME     callStack; | ||||
| 	BOOL           bResult; | ||||
| 	TCHAR          symInfo[BUFFERSIZE] = _T("?"); | ||||
| 	TCHAR          srcInfo[BUFFERSIZE] = _T("?"); | ||||
| 	HANDLE         hProcess = GetCurrentProcess(); | ||||
|     STACKFRAME     callStack; | ||||
|     BOOL           bResult; | ||||
|     TCHAR          symInfo[BUFFERSIZE] = _T("?"); | ||||
|     TCHAR          srcInfo[BUFFERSIZE] = _T("?"); | ||||
|     HANDLE         hProcess = GetCurrentProcess(); | ||||
| 
 | ||||
| 	// If it's not this thread, let's suspend it, and resume it at the end
 | ||||
| 	if ( hThread != GetCurrentThread() ) | ||||
| 		if ( SuspendThread( hThread ) == -1 ) | ||||
| 		{ | ||||
| 			// whaaat ?!
 | ||||
| 			etfprint(file, "Call stack info failed\n"); | ||||
| 			return; | ||||
| 		} | ||||
|     // If it's not this thread, let's suspend it, and resume it at the end
 | ||||
|     if ( hThread != GetCurrentThread() ) | ||||
|         if ( SuspendThread( hThread ) == -1 ) | ||||
|         { | ||||
|             // whaaat ?!
 | ||||
|             etfprint(file, "Call stack info failed\n"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
| 		::ZeroMemory( &callStack, sizeof(callStack) ); | ||||
| 		callStack.AddrPC.Offset    = eip; | ||||
| 		callStack.AddrStack.Offset = esp; | ||||
| 		callStack.AddrFrame.Offset = ebp; | ||||
| 		callStack.AddrPC.Mode      = AddrModeFlat; | ||||
| 		callStack.AddrStack.Mode   = AddrModeFlat; | ||||
| 		callStack.AddrFrame.Mode   = AddrModeFlat; | ||||
|         ::ZeroMemory( &callStack, sizeof(callStack) ); | ||||
|         callStack.AddrPC.Offset    = eip; | ||||
|         callStack.AddrStack.Offset = esp; | ||||
|         callStack.AddrFrame.Offset = ebp; | ||||
|         callStack.AddrPC.Mode      = AddrModeFlat; | ||||
|         callStack.AddrStack.Mode   = AddrModeFlat; | ||||
|         callStack.AddrFrame.Mode   = AddrModeFlat; | ||||
| 
 | ||||
| 		etfprint(file, "Call stack info: \n"); | ||||
| 		etfprint(file, lpszMessage); | ||||
|         etfprint(file, "Call stack info: \n"); | ||||
|         etfprint(file, lpszMessage); | ||||
| 
 | ||||
| 		PrintFunctionAndSourceInfo(file, callStack); | ||||
|         PrintFunctionAndSourceInfo(file, callStack); | ||||
| 
 | ||||
| 		for( ULONG index = 0; ; index++ )  | ||||
| 		{ | ||||
| 			bResult = StackWalk( | ||||
| 				IMAGE_FILE_MACHINE_I386, | ||||
| 				hProcess, | ||||
| 				hThread, | ||||
| 				&callStack, | ||||
| 				NULL,  | ||||
| 				NULL, | ||||
| 				SymFunctionTableAccess, | ||||
| 				SymGetModuleBase, | ||||
| 				NULL); | ||||
|         for( ULONG index = 0; ; index++ )  | ||||
|         { | ||||
|             bResult = StackWalk( | ||||
|                 IMAGE_FILE_MACHINE_I386, | ||||
|                 hProcess, | ||||
|                 hThread, | ||||
|                 &callStack, | ||||
|                 NULL,  | ||||
|                 NULL, | ||||
|                 SymFunctionTableAccess, | ||||
|                 SymGetModuleBase, | ||||
|                 NULL); | ||||
| 
 | ||||
| 			if ( index == 0 ) | ||||
| 				continue; | ||||
|             if ( index == 0 ) | ||||
|                 continue; | ||||
| 
 | ||||
| 			if( !bResult || callStack.AddrFrame.Offset == 0 )  | ||||
| 				break; | ||||
|             if( !bResult || callStack.AddrFrame.Offset == 0 )  | ||||
|                 break; | ||||
| 
 | ||||
| 			PrintFunctionAndSourceInfo(file, callStack); | ||||
| 		} | ||||
|             PrintFunctionAndSourceInfo(file, callStack); | ||||
|         } | ||||
| 
 | ||||
| 		if ( hThread != GetCurrentThread() ) | ||||
| 			ResumeThread( hThread ); | ||||
|         if ( hThread != GetCurrentThread() ) | ||||
|             ResumeThread( hThread ); | ||||
| } | ||||
| 
 | ||||
| char g_uefbuf[2048]; | ||||
| 
 | ||||
| void etfprintf(FILE *file, const char *format, ...) | ||||
| { | ||||
| 	va_list ap; | ||||
| 	va_start(ap, format); | ||||
| 	int len = vsprintf(g_uefbuf, format, ap); | ||||
| 	fwrite(g_uefbuf, 1, len, file); | ||||
| 	va_end(ap); | ||||
|     va_list ap; | ||||
|     va_start(ap, format); | ||||
|     int len = vsprintf(g_uefbuf, format, ap); | ||||
|     fwrite(g_uefbuf, 1, len, file); | ||||
|     va_end(ap); | ||||
| } | ||||
| 
 | ||||
| void etfprint(FILE *file, const std::string &text) | ||||
| { | ||||
| 	size_t len = text.length(); | ||||
| 	fwrite(text.data(), 1, len, file); | ||||
|     size_t len = text.length(); | ||||
|     fwrite(text.data(), 1, len, file); | ||||
| } | ||||
| 
 | ||||
| #endif //WIN32
 | ||||
|  |  | |||
|  | @ -24,9 +24,9 @@ | |||
| 
 | ||||
| #pragma comment( lib, "imagehlp.lib" ) | ||||
| 
 | ||||
| #define EXTENDEDTRACEINITIALIZE( IniSymbolPath )	InitSymInfo( IniSymbolPath ) | ||||
| #define EXTENDEDTRACEUNINITIALIZE()					UninitSymInfo() | ||||
| #define STACKTRACE(file)							StackTrace( GetCurrentThread(), "", file) | ||||
| #define EXTENDEDTRACEINITIALIZE( IniSymbolPath )    InitSymInfo( IniSymbolPath ) | ||||
| #define EXTENDEDTRACEUNINITIALIZE()                    UninitSymInfo() | ||||
| #define STACKTRACE(file)                            StackTrace( GetCurrentThread(), "", file) | ||||
| #define STACKTRACE2(file, eip, esp, ebp) StackTrace(GetCurrentThread(), "", file, eip, esp, ebp) | ||||
| // class File;
 | ||||
| 
 | ||||
|  | @ -41,13 +41,13 @@ void etfprint(FILE *file, const std::string &text); | |||
| #define UEFBUFSIZE 2048 | ||||
| extern char g_uefbuf[UEFBUFSIZE]; | ||||
| 
 | ||||
| #else	// not WIN32
 | ||||
| #else    // not WIN32
 | ||||
| 
 | ||||
| #define EXTENDEDTRACEINITIALIZE( IniSymbolPath )	((void)0) | ||||
| #define EXTENDEDTRACEUNINITIALIZE()					((void)0) | ||||
| #define STACKTRACE(file)							((void)0) | ||||
| #define STACKTRACE2(file, eip, esp, ebp)			((void)0) | ||||
| #define EXTENDEDTRACEINITIALIZE( IniSymbolPath )    ((void)0) | ||||
| #define EXTENDEDTRACEUNINITIALIZE()                    ((void)0) | ||||
| #define STACKTRACE(file)                            ((void)0) | ||||
| #define STACKTRACE2(file, eip, esp, ebp)            ((void)0) | ||||
| 
 | ||||
| #endif	// WIN32
 | ||||
| #endif    // WIN32
 | ||||
| 
 | ||||
| #endif	// _EXTENDEDTRACE_H_INCLUDED_
 | ||||
| #endif    // _EXTENDEDTRACE_H_INCLUDED_
 | ||||
|  |  | |||
|  | @ -14,100 +14,100 @@ template <typename T> | |||
| class FifoQueue | ||||
| { | ||||
| public: | ||||
| 	FifoQueue() : m_size(0) | ||||
| 	{ | ||||
| 		 m_write_ptr = m_read_ptr = new ElementPtr(); | ||||
| 	} | ||||
|     FifoQueue() : m_size(0) | ||||
|     { | ||||
|          m_write_ptr = m_read_ptr = new ElementPtr(); | ||||
|     } | ||||
| 
 | ||||
| 	~FifoQueue() | ||||
| 	{ | ||||
| 		// this will empty out the whole queue
 | ||||
| 		delete m_read_ptr; | ||||
| 	} | ||||
|     ~FifoQueue() | ||||
|     { | ||||
|         // this will empty out the whole queue
 | ||||
|         delete m_read_ptr; | ||||
|     } | ||||
| 
 | ||||
| 	u32 Size() const | ||||
| 	{ | ||||
| 		return m_size; | ||||
| 	} | ||||
|     u32 Size() const | ||||
|     { | ||||
|         return m_size; | ||||
|     } | ||||
| 
 | ||||
| 	bool Empty() const | ||||
| 	{ | ||||
| 		//return (m_read_ptr == m_write_ptr);
 | ||||
| 		return (0 == m_size); | ||||
| 	} | ||||
|     bool Empty() const | ||||
|     { | ||||
|         //return (m_read_ptr == m_write_ptr);
 | ||||
|         return (0 == m_size); | ||||
|     } | ||||
| 
 | ||||
| 	T& Front() const | ||||
| 	{ | ||||
| 		return *m_read_ptr->current; | ||||
| 	} | ||||
|     T& Front() const | ||||
|     { | ||||
|         return *m_read_ptr->current; | ||||
|     } | ||||
| 
 | ||||
| 	template <typename Arg> | ||||
| 	void Push(Arg&& t) | ||||
| 	{ | ||||
| 		// create the element, add it to the queue
 | ||||
| 		m_write_ptr->current = new T(std::forward<Arg>(t)); | ||||
| 		// set the next pointer to a new element ptr
 | ||||
| 		// then advance the write pointer 
 | ||||
| 		m_write_ptr = m_write_ptr->next = new ElementPtr(); | ||||
| 		Common::AtomicIncrement(m_size); | ||||
| 	} | ||||
|     template <typename Arg> | ||||
|     void Push(Arg&& t) | ||||
|     { | ||||
|         // create the element, add it to the queue
 | ||||
|         m_write_ptr->current = new T(std::forward<Arg>(t)); | ||||
|         // set the next pointer to a new element ptr
 | ||||
|         // then advance the write pointer 
 | ||||
|         m_write_ptr = m_write_ptr->next = new ElementPtr(); | ||||
|         Common::AtomicIncrement(m_size); | ||||
|     } | ||||
| 
 | ||||
| 	void Pop() | ||||
| 	{ | ||||
| 		Common::AtomicDecrement(m_size); | ||||
| 		ElementPtr *const tmpptr = m_read_ptr; | ||||
| 		// advance the read pointer
 | ||||
| 		m_read_ptr = m_read_ptr->next; | ||||
| 		// set the next element to NULL to stop the recursive deletion
 | ||||
| 		tmpptr->next = NULL; | ||||
| 		delete tmpptr;	// this also deletes the element
 | ||||
| 	} | ||||
|     void Pop() | ||||
|     { | ||||
|         Common::AtomicDecrement(m_size); | ||||
|         ElementPtr *const tmpptr = m_read_ptr; | ||||
|         // advance the read pointer
 | ||||
|         m_read_ptr = m_read_ptr->next; | ||||
|         // set the next element to NULL to stop the recursive deletion
 | ||||
|         tmpptr->next = NULL; | ||||
|         delete tmpptr;    // this also deletes the element
 | ||||
|     } | ||||
| 
 | ||||
| 	bool Pop(T& t) | ||||
| 	{ | ||||
| 		if (Empty()) | ||||
| 			return false; | ||||
|     bool Pop(T& t) | ||||
|     { | ||||
|         if (Empty()) | ||||
|             return false; | ||||
| 
 | ||||
| 		t = std::move(Front()); | ||||
| 		Pop(); | ||||
|         t = std::move(Front()); | ||||
|         Pop(); | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| 	// not thread-safe
 | ||||
| 	void Clear() | ||||
| 	{ | ||||
| 		m_size = 0; | ||||
| 		delete m_read_ptr; | ||||
| 		m_write_ptr = m_read_ptr = new ElementPtr(); | ||||
| 	} | ||||
|     // not thread-safe
 | ||||
|     void Clear() | ||||
|     { | ||||
|         m_size = 0; | ||||
|         delete m_read_ptr; | ||||
|         m_write_ptr = m_read_ptr = new ElementPtr(); | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| 	// stores a pointer to element
 | ||||
| 	// and a pointer to the next ElementPtr
 | ||||
| 	class ElementPtr | ||||
| 	{ | ||||
| 	public: | ||||
| 		ElementPtr() : current(NULL), next(NULL) {} | ||||
|     // stores a pointer to element
 | ||||
|     // and a pointer to the next ElementPtr
 | ||||
|     class ElementPtr | ||||
|     { | ||||
|     public: | ||||
|         ElementPtr() : current(NULL), next(NULL) {} | ||||
| 
 | ||||
| 		~ElementPtr() | ||||
| 		{ | ||||
| 			if (current) | ||||
| 			{ | ||||
| 				delete current; | ||||
| 				// recusion ftw
 | ||||
| 				if (next) | ||||
| 					delete next; | ||||
| 			} | ||||
| 		} | ||||
|         ~ElementPtr() | ||||
|         { | ||||
|             if (current) | ||||
|             { | ||||
|                 delete current; | ||||
|                 // recusion ftw
 | ||||
|                 if (next) | ||||
|                     delete next; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 		T *volatile current; | ||||
| 		ElementPtr *volatile next; | ||||
| 	}; | ||||
|         T *volatile current; | ||||
|         ElementPtr *volatile next; | ||||
|     }; | ||||
| 
 | ||||
| 	ElementPtr *volatile m_write_ptr; | ||||
| 	ElementPtr *volatile m_read_ptr; | ||||
| 	volatile u32 m_size; | ||||
|     ElementPtr *volatile m_write_ptr; | ||||
|     ElementPtr *volatile m_read_ptr; | ||||
|     volatile u32 m_size; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -22,85 +22,85 @@ | |||
| 
 | ||||
| CFileSearch::CFileSearch(const CFileSearch::XStringVector& _rSearchStrings, const CFileSearch::XStringVector& _rDirectories) | ||||
| { | ||||
| 	// Reverse the loop order for speed?
 | ||||
| 	for (size_t j = 0; j < _rSearchStrings.size(); j++) | ||||
| 	{ | ||||
| 		for (size_t i = 0; i < _rDirectories.size(); i++) | ||||
| 		{ | ||||
| 			FindFiles(_rSearchStrings[j], _rDirectories[i]); | ||||
| 		} | ||||
| 	} | ||||
|     // Reverse the loop order for speed?
 | ||||
|     for (size_t j = 0; j < _rSearchStrings.size(); j++) | ||||
|     { | ||||
|         for (size_t i = 0; i < _rDirectories.size(); i++) | ||||
|         { | ||||
|             FindFiles(_rSearchStrings[j], _rDirectories[i]); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void CFileSearch::FindFiles(const std::string& _searchString, const std::string& _strPath) | ||||
| { | ||||
| 	std::string GCMSearchPath; | ||||
| 	BuildCompleteFilename(GCMSearchPath, _strPath, _searchString); | ||||
|     std::string GCMSearchPath; | ||||
|     BuildCompleteFilename(GCMSearchPath, _strPath, _searchString); | ||||
| #ifdef _WIN32 | ||||
| 	WIN32_FIND_DATA findData; | ||||
| 	HANDLE FindFirst = FindFirstFile(UTF8ToTStr(GCMSearchPath).c_str(), &findData); | ||||
|     WIN32_FIND_DATA findData; | ||||
|     HANDLE FindFirst = FindFirstFile(UTF8ToTStr(GCMSearchPath).c_str(), &findData); | ||||
| 
 | ||||
| 	if (FindFirst != INVALID_HANDLE_VALUE) | ||||
| 	{ | ||||
| 		bool bkeepLooping = true; | ||||
|     if (FindFirst != INVALID_HANDLE_VALUE) | ||||
|     { | ||||
|         bool bkeepLooping = true; | ||||
| 
 | ||||
| 		while (bkeepLooping) | ||||
| 		{			 | ||||
| 			if (findData.cFileName[0] != '.') | ||||
| 			{ | ||||
| 				std::string strFilename; | ||||
| 				BuildCompleteFilename(strFilename, _strPath, TStrToUTF8(findData.cFileName)); | ||||
| 				m_FileNames.push_back(strFilename); | ||||
| 			} | ||||
|         while (bkeepLooping) | ||||
|         {             | ||||
|             if (findData.cFileName[0] != '.') | ||||
|             { | ||||
|                 std::string strFilename; | ||||
|                 BuildCompleteFilename(strFilename, _strPath, TStrToUTF8(findData.cFileName)); | ||||
|                 m_FileNames.push_back(strFilename); | ||||
|             } | ||||
| 
 | ||||
| 			bkeepLooping = FindNextFile(FindFirst, &findData) ? true : false; | ||||
| 		} | ||||
| 	} | ||||
| 	FindClose(FindFirst); | ||||
|             bkeepLooping = FindNextFile(FindFirst, &findData) ? true : false; | ||||
|         } | ||||
|     } | ||||
|     FindClose(FindFirst); | ||||
| 
 | ||||
| 
 | ||||
| #else | ||||
| 	// TODO: super lame/broken
 | ||||
|     // TODO: super lame/broken
 | ||||
| 
 | ||||
| 	auto end_match(_searchString); | ||||
|     auto end_match(_searchString); | ||||
| 
 | ||||
| 	// assuming we have a "*.blah"-like pattern
 | ||||
| 	if (!end_match.empty() && end_match[0] == '*') | ||||
| 		end_match.erase(0, 1); | ||||
|     // assuming we have a "*.blah"-like pattern
 | ||||
|     if (!end_match.empty() && end_match[0] == '*') | ||||
|         end_match.erase(0, 1); | ||||
| 
 | ||||
| 	// ugly
 | ||||
| 	if (end_match == ".*") | ||||
| 		end_match.clear(); | ||||
|     // ugly
 | ||||
|     if (end_match == ".*") | ||||
|         end_match.clear(); | ||||
| 
 | ||||
| 	DIR* dir = opendir(_strPath.c_str()); | ||||
|     DIR* dir = opendir(_strPath.c_str()); | ||||
| 
 | ||||
| 	if (!dir) | ||||
| 		return; | ||||
|     if (!dir) | ||||
|         return; | ||||
| 
 | ||||
| 	while (auto const dp = readdir(dir)) | ||||
| 	{ | ||||
| 		std::string found(dp->d_name); | ||||
|     while (auto const dp = readdir(dir)) | ||||
|     { | ||||
|         std::string found(dp->d_name); | ||||
| 
 | ||||
| 		if ((found != ".") && (found != "..") | ||||
| 			&& (found.size() >= end_match.size()) | ||||
| 			&& std::equal(end_match.rbegin(), end_match.rend(), found.rbegin())) | ||||
| 		{ | ||||
| 			std::string full_name; | ||||
| 			if (_strPath.c_str()[_strPath.size()-1] == DIR_SEP_CHR) | ||||
| 				full_name = _strPath + found; | ||||
| 			else | ||||
| 				full_name = _strPath + DIR_SEP + found; | ||||
|         if ((found != ".") && (found != "..") | ||||
|             && (found.size() >= end_match.size()) | ||||
|             && std::equal(end_match.rbegin(), end_match.rend(), found.rbegin())) | ||||
|         { | ||||
|             std::string full_name; | ||||
|             if (_strPath.c_str()[_strPath.size()-1] == DIR_SEP_CHR) | ||||
|                 full_name = _strPath + found; | ||||
|             else | ||||
|                 full_name = _strPath + DIR_SEP + found; | ||||
| 
 | ||||
| 			m_FileNames.push_back(full_name); | ||||
| 		} | ||||
| 	} | ||||
|             m_FileNames.push_back(full_name); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	closedir(dir); | ||||
|     closedir(dir); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| const CFileSearch::XStringVector& CFileSearch::GetFileNames() const | ||||
| { | ||||
| 	return m_FileNames; | ||||
|     return m_FileNames; | ||||
| } | ||||
|  |  | |||
|  | @ -12,16 +12,16 @@ | |||
| class CFileSearch | ||||
| { | ||||
| public: | ||||
| 	typedef std::vector<std::string>XStringVector; | ||||
|     typedef std::vector<std::string>XStringVector; | ||||
| 
 | ||||
| 	CFileSearch(const XStringVector& _rSearchStrings, const XStringVector& _rDirectories); | ||||
| 	const XStringVector& GetFileNames() const; | ||||
|     CFileSearch(const XStringVector& _rSearchStrings, const XStringVector& _rDirectories); | ||||
|     const XStringVector& GetFileNames() const; | ||||
| 
 | ||||
| private: | ||||
| 
 | ||||
| 	void FindFiles(const std::string& _searchString, const std::string& _strPath); | ||||
|     void FindFiles(const std::string& _searchString, const std::string& _strPath); | ||||
| 
 | ||||
| 	XStringVector m_FileNames; | ||||
|     XStringVector m_FileNames; | ||||
| }; | ||||
| 
 | ||||
| #endif // _FILESEARCH_H_
 | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -16,59 +16,59 @@ | |||
| template <class T, int N> | ||||
| class fixed_size_queue.h | ||||
| { | ||||
| 	T *storage; | ||||
| 	int head; | ||||
| 	int tail; | ||||
| 	int count;  // sacrifice 4 bytes for a simpler implementation. may optimize away in the future.
 | ||||
|     T *storage; | ||||
|     int head; | ||||
|     int tail; | ||||
|     int count;  // sacrifice 4 bytes for a simpler implementation. may optimize away in the future.
 | ||||
| 
 | ||||
| 	// Make copy constructor private for now.
 | ||||
| 	fixed_size_queue.h(fixed_size_queue.h &other) {	} | ||||
|     // Make copy constructor private for now.
 | ||||
|     fixed_size_queue.h(fixed_size_queue.h &other) {    } | ||||
| 
 | ||||
| public: | ||||
| 	fixed_size_queue.h() | ||||
| 	{ | ||||
| 		storage = new T[N]; | ||||
| 		clear(); | ||||
| 	} | ||||
|     fixed_size_queue.h() | ||||
|     { | ||||
|         storage = new T[N]; | ||||
|         clear(); | ||||
|     } | ||||
| 
 | ||||
| 	~fixed_size_queue.h() | ||||
| 	{ | ||||
| 		delete [] storage; | ||||
| 	} | ||||
|     ~fixed_size_queue.h() | ||||
|     { | ||||
|         delete [] storage; | ||||
|     } | ||||
| 
 | ||||
| 	void clear() { | ||||
| 		head = 0; | ||||
| 		tail = 0; | ||||
| 		count = 0; | ||||
| 	} | ||||
|     void clear() { | ||||
|         head = 0; | ||||
|         tail = 0; | ||||
|         count = 0; | ||||
|     } | ||||
| 
 | ||||
| 	void push(T t) { | ||||
| 		storage[tail] = t; | ||||
| 		tail++; | ||||
| 		if (tail == N) | ||||
| 			tail = 0; | ||||
| 		count++; | ||||
| 	} | ||||
|     void push(T t) { | ||||
|         storage[tail] = t; | ||||
|         tail++; | ||||
|         if (tail == N) | ||||
|             tail = 0; | ||||
|         count++; | ||||
|     } | ||||
| 
 | ||||
| 	void pop() { | ||||
| 		head++; | ||||
| 		if (head == N) | ||||
| 			head = 0; | ||||
| 		count--; | ||||
| 	} | ||||
|     void pop() { | ||||
|         head++; | ||||
|         if (head == N) | ||||
|             head = 0; | ||||
|         count--; | ||||
|     } | ||||
| 
 | ||||
| 	T pop_front() { | ||||
| 		const T &temp = storage[head]; | ||||
| 		pop(); | ||||
| 		return temp; | ||||
| 	} | ||||
|     T pop_front() { | ||||
|         const T &temp = storage[head]; | ||||
|         pop(); | ||||
|         return temp; | ||||
|     } | ||||
| 
 | ||||
| 	T &front() { return storage[head]; } | ||||
| 	const T &front() const { return storage[head]; } | ||||
|     T &front() { return storage[head]; } | ||||
|     const T &front() const { return storage[head]; } | ||||
| 
 | ||||
| 	size_t size() const { | ||||
| 		return count; | ||||
| 	} | ||||
|     size_t size() const { | ||||
|         return count; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| #endif // _FIXED_SIZE_QUEUE_H_
 | ||||
|  |  | |||
|  | @ -16,29 +16,29 @@ static u64 (*ptrHashFunction)(const u8 *src, int len, u32 samples) = &GetMurmurH | |||
| // Implementation from Wikipedia.
 | ||||
| u32 HashFletcher(const u8* data_u8, size_t length) | ||||
| { | ||||
| 	const u16* data = (const u16*)data_u8; /* Pointer to the data to be summed */ | ||||
| 	size_t len = (length + 1) / 2; /* Length in 16-bit words */ | ||||
| 	u32 sum1 = 0xffff, sum2 = 0xffff; | ||||
|     const u16* data = (const u16*)data_u8; /* Pointer to the data to be summed */ | ||||
|     size_t len = (length + 1) / 2; /* Length in 16-bit words */ | ||||
|     u32 sum1 = 0xffff, sum2 = 0xffff; | ||||
| 
 | ||||
| 	while (len) | ||||
| 	{ | ||||
| 		size_t tlen = len > 360 ? 360 : len; | ||||
| 		len -= tlen; | ||||
|     while (len) | ||||
|     { | ||||
|         size_t tlen = len > 360 ? 360 : len; | ||||
|         len -= tlen; | ||||
| 
 | ||||
| 		do { | ||||
| 			sum1 += *data++; | ||||
| 			sum2 += sum1; | ||||
| 		} | ||||
| 		while (--tlen); | ||||
|         do { | ||||
|             sum1 += *data++; | ||||
|             sum2 += sum1; | ||||
|         } | ||||
|         while (--tlen); | ||||
| 
 | ||||
| 		sum1 = (sum1 & 0xffff) + (sum1 >> 16); | ||||
| 		sum2 = (sum2 & 0xffff) + (sum2 >> 16); | ||||
| 	} | ||||
|         sum1 = (sum1 & 0xffff) + (sum1 >> 16); | ||||
|         sum2 = (sum2 & 0xffff) + (sum2 >> 16); | ||||
|     } | ||||
| 
 | ||||
| 	// Second reduction step to reduce sums to 16 bits
 | ||||
| 	sum1 = (sum1 & 0xffff) + (sum1 >> 16); | ||||
| 	sum2 = (sum2 & 0xffff) + (sum2 >> 16); | ||||
| 	return(sum2 << 16 | sum1); | ||||
|     // Second reduction step to reduce sums to 16 bits
 | ||||
|     sum1 = (sum1 & 0xffff) + (sum1 >> 16); | ||||
|     sum2 = (sum2 & 0xffff) + (sum2 >> 16); | ||||
|     return(sum2 << 16 | sum1); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -48,54 +48,54 @@ u32 HashFletcher(const u8* data_u8, size_t length) | |||
| // data: Pointer to the data to be summed; len is in bytes
 | ||||
| u32 HashAdler32(const u8* data, size_t len) | ||||
| { | ||||
| 	u32 a = 1, b = 0; | ||||
|     u32 a = 1, b = 0; | ||||
| 
 | ||||
| 	while (len) | ||||
| 	{ | ||||
| 		size_t tlen = len > 5550 ? 5550 : len; | ||||
| 		len -= tlen; | ||||
|     while (len) | ||||
|     { | ||||
|         size_t tlen = len > 5550 ? 5550 : len; | ||||
|         len -= tlen; | ||||
| 
 | ||||
| 		do | ||||
| 		{ | ||||
| 			a += *data++; | ||||
| 			b += a; | ||||
| 		} | ||||
| 		while (--tlen); | ||||
|         do | ||||
|         { | ||||
|             a += *data++; | ||||
|             b += a; | ||||
|         } | ||||
|         while (--tlen); | ||||
| 
 | ||||
| 		a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER); | ||||
| 		b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); | ||||
| 	} | ||||
|         a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER); | ||||
|         b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); | ||||
|     } | ||||
| 
 | ||||
| 	// It can be shown that a <= 0x1013a here, so a single subtract will do.
 | ||||
| 	if (a >= MOD_ADLER) | ||||
| 	{ | ||||
| 		a -= MOD_ADLER; | ||||
| 	} | ||||
|     // It can be shown that a <= 0x1013a here, so a single subtract will do.
 | ||||
|     if (a >= MOD_ADLER) | ||||
|     { | ||||
|         a -= MOD_ADLER; | ||||
|     } | ||||
| 
 | ||||
| 	// It can be shown that b can reach 0xfff87 here.
 | ||||
| 	b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); | ||||
|     // It can be shown that b can reach 0xfff87 here.
 | ||||
|     b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); | ||||
| 
 | ||||
| 	if (b >= MOD_ADLER) | ||||
| 	{ | ||||
| 		b -= MOD_ADLER; | ||||
| 	} | ||||
|     if (b >= MOD_ADLER) | ||||
|     { | ||||
|         b -= MOD_ADLER; | ||||
|     } | ||||
| 
 | ||||
| 	return((b << 16) | a); | ||||
|     return((b << 16) | a); | ||||
| } | ||||
| 
 | ||||
| // Stupid hash - but can't go back now :)
 | ||||
| // Don't use for new things. At least it's reasonably fast.
 | ||||
| u32 HashEctor(const u8* ptr, int length) | ||||
| { | ||||
| 	u32 crc = 0; | ||||
|     u32 crc = 0; | ||||
| 
 | ||||
| 	for (int i = 0; i < length; i++) | ||||
| 	{ | ||||
| 		crc ^= ptr[i]; | ||||
| 		crc = (crc << 3) | (crc >> 29); | ||||
| 	} | ||||
|     for (int i = 0; i < length; i++) | ||||
|     { | ||||
|         crc ^= ptr[i]; | ||||
|         crc = (crc << 3) | (crc >> 29); | ||||
|     } | ||||
| 
 | ||||
| 	return(crc); | ||||
|     return(crc); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -107,7 +107,7 @@ u32 HashEctor(const u8* ptr, int length) | |||
| 
 | ||||
| inline u64 getblock(const u64 * p, int i) | ||||
| { | ||||
| 	return p[i]; | ||||
|     return p[i]; | ||||
| } | ||||
| 
 | ||||
| //----------
 | ||||
|  | @ -115,25 +115,25 @@ inline u64 getblock(const u64 * p, int i) | |||
| 
 | ||||
| inline void bmix64(u64 & h1, u64 & h2, u64 & k1, u64 & k2, u64 & c1, u64 & c2) | ||||
| { | ||||
| 	k1 *= c1;  | ||||
| 	k1  = _rotl64(k1,23);  | ||||
| 	k1 *= c2; | ||||
| 	h1 ^= k1; | ||||
| 	h1 += h2; | ||||
|     k1 *= c1;  | ||||
|     k1  = _rotl64(k1,23);  | ||||
|     k1 *= c2; | ||||
|     h1 ^= k1; | ||||
|     h1 += h2; | ||||
| 
 | ||||
| 	h2 = _rotl64(h2,41); | ||||
|     h2 = _rotl64(h2,41); | ||||
| 
 | ||||
| 	k2 *= c2;  | ||||
| 	k2  = _rotl64(k2,23); | ||||
| 	k2 *= c1; | ||||
| 	h2 ^= k2; | ||||
| 	h2 += h1; | ||||
|     k2 *= c2;  | ||||
|     k2  = _rotl64(k2,23); | ||||
|     k2 *= c1; | ||||
|     h2 ^= k2; | ||||
|     h2 += h1; | ||||
| 
 | ||||
| 	h1 = h1*3+0x52dce729; | ||||
| 	h2 = h2*3+0x38495ab5; | ||||
|     h1 = h1*3+0x52dce729; | ||||
|     h2 = h2*3+0x38495ab5; | ||||
| 
 | ||||
| 	c1 = c1*5+0x7b7d159c; | ||||
| 	c2 = c2*5+0x6bce6396; | ||||
|     c1 = c1*5+0x7b7d159c; | ||||
|     c2 = c2*5+0x6bce6396; | ||||
| } | ||||
| 
 | ||||
| //----------
 | ||||
|  | @ -141,87 +141,87 @@ inline void bmix64(u64 & h1, u64 & h2, u64 & k1, u64 & k2, u64 & c1, u64 & c2) | |||
| 
 | ||||
| inline u64 fmix64(u64 k) | ||||
| { | ||||
| 	k ^= k >> 33; | ||||
| 	k *= 0xff51afd7ed558ccd; | ||||
| 	k ^= k >> 33; | ||||
| 	k *= 0xc4ceb9fe1a85ec53; | ||||
| 	k ^= k >> 33; | ||||
|     k ^= k >> 33; | ||||
|     k *= 0xff51afd7ed558ccd; | ||||
|     k ^= k >> 33; | ||||
|     k *= 0xc4ceb9fe1a85ec53; | ||||
|     k ^= k >> 33; | ||||
| 
 | ||||
| 	return k; | ||||
|     return k; | ||||
| } | ||||
| 
 | ||||
| u64 GetMurmurHash3(const u8 *src, int len, u32 samples) | ||||
| { | ||||
| 	const u8 * data = (const u8*)src; | ||||
| 	const int nblocks = len / 16; | ||||
| 	u32 Step = (len / 8); | ||||
| 	if(samples == 0) samples = max(Step, 1u); | ||||
| 	Step = Step / samples; | ||||
| 	if(Step < 1) Step = 1; | ||||
|     const u8 * data = (const u8*)src; | ||||
|     const int nblocks = len / 16; | ||||
|     u32 Step = (len / 8); | ||||
|     if(samples == 0) samples = max(Step, 1u); | ||||
|     Step = Step / samples; | ||||
|     if(Step < 1) Step = 1; | ||||
| 
 | ||||
| 	u64 h1 = 0x9368e53c2f6af274; | ||||
| 	u64 h2 = 0x586dcd208f7cd3fd; | ||||
|     u64 h1 = 0x9368e53c2f6af274; | ||||
|     u64 h2 = 0x586dcd208f7cd3fd; | ||||
| 
 | ||||
| 	u64 c1 = 0x87c37b91114253d5; | ||||
| 	u64 c2 = 0x4cf5ad432745937f; | ||||
|     u64 c1 = 0x87c37b91114253d5; | ||||
|     u64 c2 = 0x4cf5ad432745937f; | ||||
| 
 | ||||
| 
 | ||||
| 	//----------
 | ||||
| 	// body
 | ||||
|     //----------
 | ||||
|     // body
 | ||||
| 
 | ||||
| 	const u64 * blocks = (const u64 *)(data); | ||||
|     const u64 * blocks = (const u64 *)(data); | ||||
| 
 | ||||
| 	for(int i = 0; i < nblocks; i+=Step) | ||||
| 	{ | ||||
| 		u64 k1 = getblock(blocks,i*2+0); | ||||
| 		u64 k2 = getblock(blocks,i*2+1); | ||||
|     for(int i = 0; i < nblocks; i+=Step) | ||||
|     { | ||||
|         u64 k1 = getblock(blocks,i*2+0); | ||||
|         u64 k2 = getblock(blocks,i*2+1); | ||||
| 
 | ||||
| 		bmix64(h1,h2,k1,k2,c1,c2); | ||||
| 	} | ||||
|         bmix64(h1,h2,k1,k2,c1,c2); | ||||
|     } | ||||
| 
 | ||||
| 	//----------
 | ||||
| 	// tail
 | ||||
|     //----------
 | ||||
|     // tail
 | ||||
| 
 | ||||
| 	const u8 * tail = (const u8*)(data + nblocks*16); | ||||
|     const u8 * tail = (const u8*)(data + nblocks*16); | ||||
| 
 | ||||
| 	u64 k1 = 0; | ||||
| 	u64 k2 = 0; | ||||
|     u64 k1 = 0; | ||||
|     u64 k2 = 0; | ||||
| 
 | ||||
| 	switch(len & 15) | ||||
| 	{ | ||||
| 	case 15: k2 ^= u64(tail[14]) << 48; | ||||
| 	case 14: k2 ^= u64(tail[13]) << 40; | ||||
| 	case 13: k2 ^= u64(tail[12]) << 32; | ||||
| 	case 12: k2 ^= u64(tail[11]) << 24; | ||||
| 	case 11: k2 ^= u64(tail[10]) << 16; | ||||
| 	case 10: k2 ^= u64(tail[ 9]) << 8; | ||||
| 	case  9: k2 ^= u64(tail[ 8]) << 0; | ||||
|     switch(len & 15) | ||||
|     { | ||||
|     case 15: k2 ^= u64(tail[14]) << 48; | ||||
|     case 14: k2 ^= u64(tail[13]) << 40; | ||||
|     case 13: k2 ^= u64(tail[12]) << 32; | ||||
|     case 12: k2 ^= u64(tail[11]) << 24; | ||||
|     case 11: k2 ^= u64(tail[10]) << 16; | ||||
|     case 10: k2 ^= u64(tail[ 9]) << 8; | ||||
|     case  9: k2 ^= u64(tail[ 8]) << 0; | ||||
| 
 | ||||
| 	case  8: k1 ^= u64(tail[ 7]) << 56; | ||||
| 	case  7: k1 ^= u64(tail[ 6]) << 48; | ||||
| 	case  6: k1 ^= u64(tail[ 5]) << 40; | ||||
| 	case  5: k1 ^= u64(tail[ 4]) << 32; | ||||
| 	case  4: k1 ^= u64(tail[ 3]) << 24; | ||||
| 	case  3: k1 ^= u64(tail[ 2]) << 16; | ||||
| 	case  2: k1 ^= u64(tail[ 1]) << 8; | ||||
| 	case  1: k1 ^= u64(tail[ 0]) << 0; | ||||
| 			bmix64(h1,h2,k1,k2,c1,c2); | ||||
| 	}; | ||||
|     case  8: k1 ^= u64(tail[ 7]) << 56; | ||||
|     case  7: k1 ^= u64(tail[ 6]) << 48; | ||||
|     case  6: k1 ^= u64(tail[ 5]) << 40; | ||||
|     case  5: k1 ^= u64(tail[ 4]) << 32; | ||||
|     case  4: k1 ^= u64(tail[ 3]) << 24; | ||||
|     case  3: k1 ^= u64(tail[ 2]) << 16; | ||||
|     case  2: k1 ^= u64(tail[ 1]) << 8; | ||||
|     case  1: k1 ^= u64(tail[ 0]) << 0; | ||||
|             bmix64(h1,h2,k1,k2,c1,c2); | ||||
|     }; | ||||
| 
 | ||||
| 	//----------
 | ||||
| 	// finalization
 | ||||
|     //----------
 | ||||
|     // finalization
 | ||||
| 
 | ||||
| 	h2 ^= len; | ||||
|     h2 ^= len; | ||||
| 
 | ||||
| 	h1 += h2; | ||||
| 	h2 += h1; | ||||
|     h1 += h2; | ||||
|     h2 += h1; | ||||
| 
 | ||||
| 	h1 = fmix64(h1); | ||||
| 	h2 = fmix64(h2); | ||||
|     h1 = fmix64(h1); | ||||
|     h2 = fmix64(h2); | ||||
| 
 | ||||
| 	h1 += h2; | ||||
|     h1 += h2; | ||||
| 
 | ||||
| 	return h1; | ||||
|     return h1; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -229,23 +229,23 @@ u64 GetMurmurHash3(const u8 *src, int len, u32 samples) | |||
| u64 GetCRC32(const u8 *src, int len, u32 samples) | ||||
| { | ||||
| #if _M_SSE >= 0x402 | ||||
| 	u64 h = len; | ||||
| 	u32 Step = (len / 8); | ||||
| 	const u64 *data = (const u64 *)src; | ||||
| 	const u64 *end = data + Step; | ||||
| 	if(samples == 0) samples = max(Step, 1u); | ||||
| 	Step = Step / samples; | ||||
| 	if(Step < 1) Step = 1; | ||||
| 	while(data < end) | ||||
| 	{ | ||||
| 		h = _mm_crc32_u64(h, data[0]); | ||||
| 		data += Step; | ||||
| 	} | ||||
|     u64 h = len; | ||||
|     u32 Step = (len / 8); | ||||
|     const u64 *data = (const u64 *)src; | ||||
|     const u64 *end = data + Step; | ||||
|     if(samples == 0) samples = max(Step, 1u); | ||||
|     Step = Step / samples; | ||||
|     if(Step < 1) Step = 1; | ||||
|     while(data < end) | ||||
|     { | ||||
|         h = _mm_crc32_u64(h, data[0]); | ||||
|         data += Step; | ||||
|     } | ||||
| 
 | ||||
| 	const u8 *data2 = (const u8*)end; | ||||
| 	return _mm_crc32_u64(h, u64(data2[0])); | ||||
|     const u8 *data2 = (const u8*)end; | ||||
|     return _mm_crc32_u64(h, u64(data2[0])); | ||||
| #else | ||||
| 	return 0; | ||||
|     return 0; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  | @ -259,68 +259,68 @@ u64 GetCRC32(const u8 *src, int len, u32 samples) | |||
|  */ | ||||
| u64 GetHashHiresTexture(const u8 *src, int len, u32 samples) | ||||
| { | ||||
| 	const u64 m = 0xc6a4a7935bd1e995; | ||||
| 	u64 h = len * m; | ||||
| 	const int r = 47; | ||||
| 	u32 Step = (len / 8); | ||||
| 	const u64 *data = (const u64 *)src; | ||||
| 	const u64 *end = data + Step; | ||||
| 	if(samples == 0) samples = max(Step, 1u); | ||||
| 	Step = Step / samples; | ||||
| 	if(Step < 1) Step = 1; | ||||
| 	while(data < end) | ||||
| 	{ | ||||
| 		u64 k = data[0]; | ||||
| 		data+=Step; | ||||
| 		k *= m; | ||||
| 		k ^= k >> r;  | ||||
| 		k *= m; | ||||
| 		h ^= k; | ||||
| 		h *= m; | ||||
| 	} | ||||
|     const u64 m = 0xc6a4a7935bd1e995; | ||||
|     u64 h = len * m; | ||||
|     const int r = 47; | ||||
|     u32 Step = (len / 8); | ||||
|     const u64 *data = (const u64 *)src; | ||||
|     const u64 *end = data + Step; | ||||
|     if(samples == 0) samples = max(Step, 1u); | ||||
|     Step = Step / samples; | ||||
|     if(Step < 1) Step = 1; | ||||
|     while(data < end) | ||||
|     { | ||||
|         u64 k = data[0]; | ||||
|         data+=Step; | ||||
|         k *= m; | ||||
|         k ^= k >> r;  | ||||
|         k *= m; | ||||
|         h ^= k; | ||||
|         h *= m; | ||||
|     } | ||||
| 
 | ||||
| 	const u8 * data2 = (const u8*)end; | ||||
|     const u8 * data2 = (const u8*)end; | ||||
| 
 | ||||
| 	switch(len & 7) | ||||
| 	{ | ||||
| 	case 7: h ^= u64(data2[6]) << 48; | ||||
| 	case 6: h ^= u64(data2[5]) << 40; | ||||
| 	case 5: h ^= u64(data2[4]) << 32; | ||||
| 	case 4: h ^= u64(data2[3]) << 24; | ||||
| 	case 3: h ^= u64(data2[2]) << 16; | ||||
| 	case 2: h ^= u64(data2[1]) << 8; | ||||
| 	case 1: h ^= u64(data2[0]); | ||||
| 			h *= m; | ||||
| 	}; | ||||
|     switch(len & 7) | ||||
|     { | ||||
|     case 7: h ^= u64(data2[6]) << 48; | ||||
|     case 6: h ^= u64(data2[5]) << 40; | ||||
|     case 5: h ^= u64(data2[4]) << 32; | ||||
|     case 4: h ^= u64(data2[3]) << 24; | ||||
|     case 3: h ^= u64(data2[2]) << 16; | ||||
|     case 2: h ^= u64(data2[1]) << 8; | ||||
|     case 1: h ^= u64(data2[0]); | ||||
|             h *= m; | ||||
|     }; | ||||
|   | ||||
| 	h ^= h >> r; | ||||
| 	h *= m; | ||||
| 	h ^= h >> r; | ||||
|     h ^= h >> r; | ||||
|     h *= m; | ||||
|     h ^= h >> r; | ||||
| 
 | ||||
| 	return h; | ||||
|     return h; | ||||
| }  | ||||
| #else | ||||
| // CRC32 hash using the SSE4.2 instruction
 | ||||
| u64 GetCRC32(const u8 *src, int len, u32 samples) | ||||
| { | ||||
| #if _M_SSE >= 0x402 | ||||
| 	u32 h = len; | ||||
| 	u32 Step = (len/4); | ||||
| 	const u32 *data = (const u32 *)src; | ||||
| 	const u32 *end = data + Step; | ||||
| 	if(samples == 0) samples = max(Step, 1u); | ||||
| 	Step  = Step / samples; | ||||
| 	if(Step < 1) Step = 1; | ||||
| 	while(data < end) | ||||
| 	{ | ||||
| 		h = _mm_crc32_u32(h, data[0]); | ||||
| 		data += Step; | ||||
| 	} | ||||
|     u32 h = len; | ||||
|     u32 Step = (len/4); | ||||
|     const u32 *data = (const u32 *)src; | ||||
|     const u32 *end = data + Step; | ||||
|     if(samples == 0) samples = max(Step, 1u); | ||||
|     Step  = Step / samples; | ||||
|     if(Step < 1) Step = 1; | ||||
|     while(data < end) | ||||
|     { | ||||
|         h = _mm_crc32_u32(h, data[0]); | ||||
|         data += Step; | ||||
|     } | ||||
| 
 | ||||
| 	const u8 *data2 = (const u8*)end; | ||||
| 	return (u64)_mm_crc32_u32(h, u32(data2[0])); | ||||
|     const u8 *data2 = (const u8*)end; | ||||
|     return (u64)_mm_crc32_u32(h, u32(data2[0])); | ||||
| #else | ||||
| 	return 0; | ||||
|     return 0; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  | @ -330,7 +330,7 @@ u64 GetCRC32(const u8 *src, int len, u32 samples) | |||
| 
 | ||||
| inline u32 getblock(const u32 * p, int i) | ||||
| { | ||||
| 	return p[i]; | ||||
|     return p[i]; | ||||
| } | ||||
| 
 | ||||
| //----------
 | ||||
|  | @ -340,107 +340,107 @@ inline u32 getblock(const u32 * p, int i) | |||
| 
 | ||||
| inline u32 fmix32(u32 h) | ||||
| { | ||||
| 	h ^= h >> 16; | ||||
| 	h *= 0x85ebca6b; | ||||
| 	h ^= h >> 13; | ||||
| 	h *= 0xc2b2ae35; | ||||
| 	h ^= h >> 16; | ||||
|     h ^= h >> 16; | ||||
|     h *= 0x85ebca6b; | ||||
|     h ^= h >> 13; | ||||
|     h *= 0xc2b2ae35; | ||||
|     h ^= h >> 16; | ||||
| 
 | ||||
| 	return h; | ||||
|     return h; | ||||
| } | ||||
| 
 | ||||
| inline void bmix32(u32 & h1, u32 & h2, u32 & k1, u32 & k2, u32 & c1, u32 & c2) | ||||
| { | ||||
| 	k1 *= c1;  | ||||
| 	k1  = _rotl(k1,11);  | ||||
| 	k1 *= c2; | ||||
| 	h1 ^= k1; | ||||
| 	h1 += h2; | ||||
|     k1 *= c1;  | ||||
|     k1  = _rotl(k1,11);  | ||||
|     k1 *= c2; | ||||
|     h1 ^= k1; | ||||
|     h1 += h2; | ||||
| 
 | ||||
| 	h2 = _rotl(h2,17); | ||||
|     h2 = _rotl(h2,17); | ||||
| 
 | ||||
| 	k2 *= c2;  | ||||
| 	k2  = _rotl(k2,11); | ||||
| 	k2 *= c1; | ||||
| 	h2 ^= k2; | ||||
| 	h2 += h1; | ||||
|     k2 *= c2;  | ||||
|     k2  = _rotl(k2,11); | ||||
|     k2 *= c1; | ||||
|     h2 ^= k2; | ||||
|     h2 += h1; | ||||
| 
 | ||||
| 	h1 = h1*3+0x52dce729; | ||||
| 	h2 = h2*3+0x38495ab5; | ||||
|     h1 = h1*3+0x52dce729; | ||||
|     h2 = h2*3+0x38495ab5; | ||||
| 
 | ||||
| 	c1 = c1*5+0x7b7d159c; | ||||
| 	c2 = c2*5+0x6bce6396; | ||||
|     c1 = c1*5+0x7b7d159c; | ||||
|     c2 = c2*5+0x6bce6396; | ||||
| } | ||||
| 
 | ||||
| //----------
 | ||||
| 
 | ||||
| u64 GetMurmurHash3(const u8* src, int len, u32 samples) | ||||
| { | ||||
| 	const u8 * data = (const u8*)src; | ||||
| 	u32 out[2]; | ||||
| 	const int nblocks = len / 8; | ||||
| 	u32 Step = (len / 4); | ||||
| 	if(samples == 0) samples = max(Step, 1u); | ||||
| 	Step = Step / samples; | ||||
| 	if(Step < 1) Step = 1; | ||||
|     const u8 * data = (const u8*)src; | ||||
|     u32 out[2]; | ||||
|     const int nblocks = len / 8; | ||||
|     u32 Step = (len / 4); | ||||
|     if(samples == 0) samples = max(Step, 1u); | ||||
|     Step = Step / samples; | ||||
|     if(Step < 1) Step = 1; | ||||
| 
 | ||||
| 	u32 h1 = 0x8de1c3ac; | ||||
| 	u32 h2 = 0xbab98226; | ||||
|     u32 h1 = 0x8de1c3ac; | ||||
|     u32 h2 = 0xbab98226; | ||||
| 
 | ||||
| 	u32 c1 = 0x95543787; | ||||
| 	u32 c2 = 0x2ad7eb25; | ||||
|     u32 c1 = 0x95543787; | ||||
|     u32 c2 = 0x2ad7eb25; | ||||
| 
 | ||||
| 	//----------
 | ||||
| 	// body
 | ||||
|     //----------
 | ||||
|     // body
 | ||||
| 
 | ||||
| 	const u32 * blocks = (const u32 *)(data + nblocks*8); | ||||
|     const u32 * blocks = (const u32 *)(data + nblocks*8); | ||||
| 
 | ||||
| 	for(int i = -nblocks; i < 0; i+=Step) | ||||
| 	{ | ||||
| 		u32 k1 = getblock(blocks,i*2+0); | ||||
| 		u32 k2 = getblock(blocks,i*2+1); | ||||
|     for(int i = -nblocks; i < 0; i+=Step) | ||||
|     { | ||||
|         u32 k1 = getblock(blocks,i*2+0); | ||||
|         u32 k2 = getblock(blocks,i*2+1); | ||||
| 
 | ||||
| 		bmix32(h1,h2,k1,k2,c1,c2); | ||||
| 	} | ||||
|         bmix32(h1,h2,k1,k2,c1,c2); | ||||
|     } | ||||
| 
 | ||||
| 	//----------
 | ||||
| 	// tail
 | ||||
| 	 | ||||
| 	const u8 * tail = (const u8*)(data + nblocks*8); | ||||
|     //----------
 | ||||
|     // tail
 | ||||
|      | ||||
|     const u8 * tail = (const u8*)(data + nblocks*8); | ||||
| 
 | ||||
| 	u32 k1 = 0; | ||||
| 	u32 k2 = 0; | ||||
|     u32 k1 = 0; | ||||
|     u32 k2 = 0; | ||||
| 
 | ||||
| 	switch(len & 7) | ||||
| 	{ | ||||
| 	case 7: k2 ^= tail[6] << 16; | ||||
| 	case 6: k2 ^= tail[5] << 8; | ||||
| 	case 5: k2 ^= tail[4] << 0; | ||||
| 	case 4: k1 ^= tail[3] << 24; | ||||
| 	case 3: k1 ^= tail[2] << 16; | ||||
| 	case 2: k1 ^= tail[1] << 8; | ||||
| 	case 1: k1 ^= tail[0] << 0; | ||||
| 	        bmix32(h1,h2,k1,k2,c1,c2); | ||||
| 	}; | ||||
|     switch(len & 7) | ||||
|     { | ||||
|     case 7: k2 ^= tail[6] << 16; | ||||
|     case 6: k2 ^= tail[5] << 8; | ||||
|     case 5: k2 ^= tail[4] << 0; | ||||
|     case 4: k1 ^= tail[3] << 24; | ||||
|     case 3: k1 ^= tail[2] << 16; | ||||
|     case 2: k1 ^= tail[1] << 8; | ||||
|     case 1: k1 ^= tail[0] << 0; | ||||
|             bmix32(h1,h2,k1,k2,c1,c2); | ||||
|     }; | ||||
| 
 | ||||
| 	//----------
 | ||||
| 	// finalization
 | ||||
|     //----------
 | ||||
|     // finalization
 | ||||
| 
 | ||||
| 	h2 ^= len; | ||||
|     h2 ^= len; | ||||
| 
 | ||||
| 	h1 += h2; | ||||
| 	h2 += h1; | ||||
|     h1 += h2; | ||||
|     h2 += h1; | ||||
| 
 | ||||
| 	h1 = fmix32(h1); | ||||
| 	h2 = fmix32(h2); | ||||
|     h1 = fmix32(h1); | ||||
|     h2 = fmix32(h2); | ||||
| 
 | ||||
| 	h1 += h2; | ||||
| 	h2 += h1; | ||||
|     h1 += h2; | ||||
|     h2 += h1; | ||||
| 
 | ||||
| 	out[0] = h1; | ||||
| 	out[1] = h2; | ||||
| 	 | ||||
| 	return *((u64 *)&out); | ||||
|     out[0] = h1; | ||||
|     out[1] = h2; | ||||
|      | ||||
|     return *((u64 *)&out); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -450,70 +450,70 @@ u64 GetMurmurHash3(const u8* src, int len, u32 samples) | |||
|  */ | ||||
| u64 GetHashHiresTexture(const u8 *src, int len, u32 samples) | ||||
| { | ||||
| 	const u64 m = 0xc6a4a7935bd1e995ULL; | ||||
| 	u64 h = len * m; | ||||
| 	const int r = 47; | ||||
| 	u32 Step = (len / 8); | ||||
| 	const u64 *data = (const u64 *)src; | ||||
| 	const u64 *end = data + Step; | ||||
| 	if(samples == 0) samples = max(Step, 1u); | ||||
| 	Step = Step / samples; | ||||
| 	if(Step < 1) Step = 1; | ||||
| 	while(data < end) | ||||
| 	{ | ||||
| 		u64 k = data[0]; | ||||
| 		data+=Step; | ||||
| 		k *= m;  | ||||
| 		k ^= k >> r;  | ||||
| 		k *= m; | ||||
| 		h ^= k; | ||||
| 		h *= m;  | ||||
| 	} | ||||
|     const u64 m = 0xc6a4a7935bd1e995ULL; | ||||
|     u64 h = len * m; | ||||
|     const int r = 47; | ||||
|     u32 Step = (len / 8); | ||||
|     const u64 *data = (const u64 *)src; | ||||
|     const u64 *end = data + Step; | ||||
|     if(samples == 0) samples = max(Step, 1u); | ||||
|     Step = Step / samples; | ||||
|     if(Step < 1) Step = 1; | ||||
|     while(data < end) | ||||
|     { | ||||
|         u64 k = data[0]; | ||||
|         data+=Step; | ||||
|         k *= m;  | ||||
|         k ^= k >> r;  | ||||
|         k *= m; | ||||
|         h ^= k; | ||||
|         h *= m;  | ||||
|     } | ||||
| 
 | ||||
| 	const u8 * data2 = (const u8*)end; | ||||
|     const u8 * data2 = (const u8*)end; | ||||
| 
 | ||||
| 	switch(len & 7) | ||||
| 	{ | ||||
| 	case 7: h ^= u64(data2[6]) << 48; | ||||
| 	case 6: h ^= u64(data2[5]) << 40; | ||||
| 	case 5: h ^= u64(data2[4]) << 32; | ||||
| 	case 4: h ^= u64(data2[3]) << 24; | ||||
| 	case 3: h ^= u64(data2[2]) << 16; | ||||
| 	case 2: h ^= u64(data2[1]) << 8; | ||||
| 	case 1: h ^= u64(data2[0]); | ||||
| 			h *= m; | ||||
| 	}; | ||||
|     switch(len & 7) | ||||
|     { | ||||
|     case 7: h ^= u64(data2[6]) << 48; | ||||
|     case 6: h ^= u64(data2[5]) << 40; | ||||
|     case 5: h ^= u64(data2[4]) << 32; | ||||
|     case 4: h ^= u64(data2[3]) << 24; | ||||
|     case 3: h ^= u64(data2[2]) << 16; | ||||
|     case 2: h ^= u64(data2[1]) << 8; | ||||
|     case 1: h ^= u64(data2[0]); | ||||
|             h *= m; | ||||
|     }; | ||||
|   | ||||
| 	h ^= h >> r; | ||||
| 	h *= m; | ||||
| 	h ^= h >> r; | ||||
|     h ^= h >> r; | ||||
|     h *= m; | ||||
|     h ^= h >> r; | ||||
| 
 | ||||
| 	return h; | ||||
|     return h; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| u64 GetHash64(const u8 *src, int len, u32 samples) | ||||
| { | ||||
| 	return ptrHashFunction(src, len, samples); | ||||
|     return ptrHashFunction(src, len, samples); | ||||
| } | ||||
| 
 | ||||
| // sets the hash function used for the texture cache
 | ||||
| void SetHash64Function(bool useHiresTextures) | ||||
| { | ||||
| 	if (useHiresTextures) | ||||
| 	{ | ||||
| 		ptrHashFunction = &GetHashHiresTexture; | ||||
| 	} | ||||
|     if (useHiresTextures) | ||||
|     { | ||||
|         ptrHashFunction = &GetHashHiresTexture; | ||||
|     } | ||||
| #if _M_SSE >= 0x402 | ||||
| 	else if (cpu_info.bSSE4_2 && !useHiresTextures) // sse crc32 version
 | ||||
| 	{ | ||||
| 		ptrHashFunction = &GetCRC32; | ||||
| 	} | ||||
|     else if (cpu_info.bSSE4_2 && !useHiresTextures) // sse crc32 version
 | ||||
|     { | ||||
|         ptrHashFunction = &GetCRC32; | ||||
|     } | ||||
| #endif | ||||
| 	else | ||||
| 	{ | ||||
| 		ptrHashFunction = &GetMurmurHash3; | ||||
| 	} | ||||
|     else | ||||
|     { | ||||
|         ptrHashFunction = &GetMurmurHash3; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ template <typename K, typename V> | |||
| class LinearDiskCacheReader | ||||
| { | ||||
| public: | ||||
| 	virtual void Read(const K &key, const V *value, u32 value_size) = 0; | ||||
|     virtual void Read(const K &key, const V *value, u32 value_size) = 0; | ||||
| }; | ||||
| 
 | ||||
| // Dead simple unsorted key-value store with append functionality.
 | ||||
|  | @ -49,143 +49,143 @@ template <typename K, typename V> | |||
| class LinearDiskCache | ||||
| { | ||||
| public: | ||||
| 	// return number of read entries
 | ||||
| 	u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader) | ||||
| 	{ | ||||
| 		using std::ios_base; | ||||
|     // return number of read entries
 | ||||
|     u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader) | ||||
|     { | ||||
|         using std::ios_base; | ||||
| 
 | ||||
| 		// close any currently opened file
 | ||||
| 		Close(); | ||||
| 		m_num_entries = 0; | ||||
|         // close any currently opened file
 | ||||
|         Close(); | ||||
|         m_num_entries = 0; | ||||
| 
 | ||||
| 		// try opening for reading/writing
 | ||||
| 		OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary); | ||||
|         // try opening for reading/writing
 | ||||
|         OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary); | ||||
| 
 | ||||
| 		m_file.seekg(0, std::ios::end); | ||||
| 		std::fstream::pos_type end_pos = m_file.tellg(); | ||||
| 		m_file.seekg(0, std::ios::beg); | ||||
| 		std::fstream::pos_type start_pos = m_file.tellg(); | ||||
| 		std::streamoff file_size = end_pos - start_pos; | ||||
| 		 | ||||
| 		if (m_file.is_open() && ValidateHeader()) | ||||
| 		{ | ||||
| 			// good header, read some key/value pairs
 | ||||
| 			K key; | ||||
|         m_file.seekg(0, std::ios::end); | ||||
|         std::fstream::pos_type end_pos = m_file.tellg(); | ||||
|         m_file.seekg(0, std::ios::beg); | ||||
|         std::fstream::pos_type start_pos = m_file.tellg(); | ||||
|         std::streamoff file_size = end_pos - start_pos; | ||||
|          | ||||
|         if (m_file.is_open() && ValidateHeader()) | ||||
|         { | ||||
|             // good header, read some key/value pairs
 | ||||
|             K key; | ||||
| 
 | ||||
| 			V *value = NULL; | ||||
| 			u32 value_size; | ||||
| 			u32 entry_number; | ||||
|             V *value = NULL; | ||||
|             u32 value_size; | ||||
|             u32 entry_number; | ||||
| 
 | ||||
| 			std::fstream::pos_type last_pos = m_file.tellg(); | ||||
|             std::fstream::pos_type last_pos = m_file.tellg(); | ||||
| 
 | ||||
| 			while (Read(&value_size)) | ||||
| 			{ | ||||
| 				std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size; | ||||
| 				if (next_extent > file_size) | ||||
| 					break; | ||||
|             while (Read(&value_size)) | ||||
|             { | ||||
|                 std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size; | ||||
|                 if (next_extent > file_size) | ||||
|                     break; | ||||
| 
 | ||||
| 				delete[] value; | ||||
| 				value = new V[value_size]; | ||||
|                 delete[] value; | ||||
|                 value = new V[value_size]; | ||||
| 
 | ||||
| 				// read key/value and pass to reader
 | ||||
| 				if (Read(&key) && | ||||
| 					Read(value, value_size) &&  | ||||
| 					Read(&entry_number) && | ||||
| 					entry_number == m_num_entries+1) | ||||
|  				{ | ||||
| 					reader.Read(key, value, value_size); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					break; | ||||
| 				} | ||||
|                 // read key/value and pass to reader
 | ||||
|                 if (Read(&key) && | ||||
|                     Read(value, value_size) &&  | ||||
|                     Read(&entry_number) && | ||||
|                     entry_number == m_num_entries+1) | ||||
|                  { | ||||
|                     reader.Read(key, value, value_size); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
| 				m_num_entries++; | ||||
| 				last_pos = m_file.tellg(); | ||||
| 			} | ||||
| 			m_file.seekp(last_pos); | ||||
| 			m_file.clear(); | ||||
|                 m_num_entries++; | ||||
|                 last_pos = m_file.tellg(); | ||||
|             } | ||||
|             m_file.seekp(last_pos); | ||||
|             m_file.clear(); | ||||
| 
 | ||||
| 			delete[] value; | ||||
| 			return m_num_entries; | ||||
| 		} | ||||
|             delete[] value; | ||||
|             return m_num_entries; | ||||
|         } | ||||
| 
 | ||||
| 		// failed to open file for reading or bad header
 | ||||
| 		// close and recreate file
 | ||||
| 		Close(); | ||||
| 		m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary); | ||||
| 		WriteHeader(); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	 | ||||
| 	void Sync() | ||||
| 	{ | ||||
| 		m_file.flush(); | ||||
| 	} | ||||
|         // failed to open file for reading or bad header
 | ||||
|         // close and recreate file
 | ||||
|         Close(); | ||||
|         m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary); | ||||
|         WriteHeader(); | ||||
|         return 0; | ||||
|     } | ||||
|      | ||||
|     void Sync() | ||||
|     { | ||||
|         m_file.flush(); | ||||
|     } | ||||
| 
 | ||||
| 	void Close() | ||||
| 	{ | ||||
| 		if (m_file.is_open()) | ||||
| 			m_file.close(); | ||||
| 		// clear any error flags
 | ||||
| 		m_file.clear(); | ||||
| 	} | ||||
|     void Close() | ||||
|     { | ||||
|         if (m_file.is_open()) | ||||
|             m_file.close(); | ||||
|         // clear any error flags
 | ||||
|         m_file.clear(); | ||||
|     } | ||||
| 
 | ||||
| 	// Appends a key-value pair to the store.
 | ||||
| 	void Append(const K &key, const V *value, u32 value_size) | ||||
| 	{ | ||||
| 		// TODO: Should do a check that we don't already have "key"? (I think each caller does that already.)
 | ||||
| 		Write(&value_size); | ||||
| 		Write(&key); | ||||
| 		Write(value, value_size); | ||||
| 		m_num_entries++; | ||||
| 		Write(&m_num_entries); | ||||
| 	} | ||||
|     // Appends a key-value pair to the store.
 | ||||
|     void Append(const K &key, const V *value, u32 value_size) | ||||
|     { | ||||
|         // TODO: Should do a check that we don't already have "key"? (I think each caller does that already.)
 | ||||
|         Write(&value_size); | ||||
|         Write(&key); | ||||
|         Write(value, value_size); | ||||
|         m_num_entries++; | ||||
|         Write(&m_num_entries); | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| 	void WriteHeader() | ||||
| 	{ | ||||
| 		Write(&m_header); | ||||
| 	} | ||||
|     void WriteHeader() | ||||
|     { | ||||
|         Write(&m_header); | ||||
|     } | ||||
| 
 | ||||
| 	bool ValidateHeader() | ||||
| 	{ | ||||
| 		char file_header[sizeof(Header)]; | ||||
|     bool ValidateHeader() | ||||
|     { | ||||
|         char file_header[sizeof(Header)]; | ||||
| 
 | ||||
| 		return (Read(file_header, sizeof(Header)) | ||||
| 			&& !memcmp((const char*)&m_header, file_header, sizeof(Header))); | ||||
| 	} | ||||
|         return (Read(file_header, sizeof(Header)) | ||||
|             && !memcmp((const char*)&m_header, file_header, sizeof(Header))); | ||||
|     } | ||||
| 
 | ||||
| 	template <typename D> | ||||
| 	bool Write(const D *data, u32 count = 1) | ||||
| 	{ | ||||
| 		return m_file.write((const char*)data, count * sizeof(D)).good(); | ||||
| 	} | ||||
|     template <typename D> | ||||
|     bool Write(const D *data, u32 count = 1) | ||||
|     { | ||||
|         return m_file.write((const char*)data, count * sizeof(D)).good(); | ||||
|     } | ||||
| 
 | ||||
| 	template <typename D> | ||||
| 	bool Read(const D *data, u32 count = 1) | ||||
| 	{ | ||||
| 		return m_file.read((char*)data, count * sizeof(D)).good(); | ||||
| 	} | ||||
|     template <typename D> | ||||
|     bool Read(const D *data, u32 count = 1) | ||||
|     { | ||||
|         return m_file.read((char*)data, count * sizeof(D)).good(); | ||||
|     } | ||||
| 
 | ||||
| 	struct Header | ||||
| 	{ | ||||
| 		Header() | ||||
| 			: id(*(u32*)"DCAC") | ||||
| 			, key_t_size(sizeof(K)) | ||||
| 			, value_t_size(sizeof(V)) | ||||
| 		{ | ||||
| 			memcpy(ver, scm_rev_git_str, 40); | ||||
| 		} | ||||
|     struct Header | ||||
|     { | ||||
|         Header() | ||||
|             : id(*(u32*)"DCAC") | ||||
|             , key_t_size(sizeof(K)) | ||||
|             , value_t_size(sizeof(V)) | ||||
|         { | ||||
|             memcpy(ver, scm_rev_git_str, 40); | ||||
|         } | ||||
| 
 | ||||
| 		const u32 id; | ||||
| 		const u16 key_t_size, value_t_size; | ||||
| 		char ver[40]; | ||||
|         const u32 id; | ||||
|         const u16 key_t_size, value_t_size; | ||||
|         char ver[40]; | ||||
| 
 | ||||
| 	} m_header; | ||||
|     } m_header; | ||||
| 
 | ||||
| 	std::fstream m_file; | ||||
| 	u32 m_num_entries; | ||||
|     std::fstream m_file; | ||||
|     u32 m_num_entries; | ||||
| }; | ||||
| 
 | ||||
| #endif  // _LINEAR_DISKCACHE
 | ||||
|  |  | |||
|  | @ -5,74 +5,74 @@ | |||
| #ifndef _LOG_H_ | ||||
| #define _LOG_H_ | ||||
| 
 | ||||
| #define	NOTICE_LEVEL  1  // VERY important information that is NOT errors. Like startup and OSReports.
 | ||||
| #define	ERROR_LEVEL   2  // Critical errors 
 | ||||
| #define	WARNING_LEVEL 3  // Something is suspicious.
 | ||||
| #define	INFO_LEVEL    4  // General information.
 | ||||
| #define	DEBUG_LEVEL   5  // Detailed debugging - might make things slow.
 | ||||
| #define    NOTICE_LEVEL  1  // VERY important information that is NOT errors. Like startup and OSReports.
 | ||||
| #define    ERROR_LEVEL   2  // Critical errors 
 | ||||
| #define    WARNING_LEVEL 3  // Something is suspicious.
 | ||||
| #define    INFO_LEVEL    4  // General information.
 | ||||
| #define    DEBUG_LEVEL   5  // Detailed debugging - might make things slow.
 | ||||
| 
 | ||||
| namespace LogTypes | ||||
| { | ||||
| 
 | ||||
| enum LOG_TYPE { | ||||
| 	ACTIONREPLAY, | ||||
| 	AUDIO, | ||||
| 	AUDIO_INTERFACE, | ||||
| 	BOOT, | ||||
| 	COMMANDPROCESSOR, | ||||
| 	COMMON, | ||||
| 	CONSOLE, | ||||
| 	DISCIO, | ||||
| 	FILEMON, | ||||
| 	DSPHLE, | ||||
| 	DSPLLE, | ||||
| 	DSP_MAIL, | ||||
| 	DSPINTERFACE, | ||||
| 	DVDINTERFACE, | ||||
| 	DYNA_REC, | ||||
| 	EXPANSIONINTERFACE, | ||||
| 	GDB_STUB, | ||||
| 	ARM11, | ||||
| 	GPFIFO, | ||||
| 	OSHLE, | ||||
| 	MASTER_LOG, | ||||
| 	MEMMAP, | ||||
| 	MEMCARD_MANAGER, | ||||
| 	OSREPORT, | ||||
| 	PAD,  | ||||
| 	PROCESSORINTERFACE, | ||||
| 	PIXELENGINE, | ||||
| 	SERIALINTERFACE, | ||||
| 	SP1, | ||||
| 	STREAMINGINTERFACE, | ||||
| 	VIDEO, | ||||
| 	VIDEOINTERFACE, | ||||
| 	LOADER, | ||||
| 	FILESYS, | ||||
| 	WII_IPC_DVD, | ||||
| 	WII_IPC_ES, | ||||
| 	WII_IPC_FILEIO, | ||||
| 	WII_IPC_HID, | ||||
| 	WII_IPC_HLE, | ||||
| 	WII_IPC_NET, | ||||
| 	WII_IPC_WC24, | ||||
| 	WII_IPC_SSL, | ||||
| 	WII_IPC_SD, | ||||
| 	WII_IPC_STM, | ||||
| 	WII_IPC_WIIMOTE, | ||||
| 	TIME, | ||||
| 	NETPLAY, | ||||
|     ACTIONREPLAY, | ||||
|     AUDIO, | ||||
|     AUDIO_INTERFACE, | ||||
|     BOOT, | ||||
|     COMMANDPROCESSOR, | ||||
|     COMMON, | ||||
|     CONSOLE, | ||||
|     DISCIO, | ||||
|     FILEMON, | ||||
|     DSPHLE, | ||||
|     DSPLLE, | ||||
|     DSP_MAIL, | ||||
|     DSPINTERFACE, | ||||
|     DVDINTERFACE, | ||||
|     DYNA_REC, | ||||
|     EXPANSIONINTERFACE, | ||||
|     GDB_STUB, | ||||
|     ARM11, | ||||
|     GPFIFO, | ||||
|     OSHLE, | ||||
|     MASTER_LOG, | ||||
|     MEMMAP, | ||||
|     MEMCARD_MANAGER, | ||||
|     OSREPORT, | ||||
|     PAD,  | ||||
|     PROCESSORINTERFACE, | ||||
|     PIXELENGINE, | ||||
|     SERIALINTERFACE, | ||||
|     SP1, | ||||
|     STREAMINGINTERFACE, | ||||
|     VIDEO, | ||||
|     VIDEOINTERFACE, | ||||
|     LOADER, | ||||
|     FILESYS, | ||||
|     WII_IPC_DVD, | ||||
|     WII_IPC_ES, | ||||
|     WII_IPC_FILEIO, | ||||
|     WII_IPC_HID, | ||||
|     WII_IPC_HLE, | ||||
|     WII_IPC_NET, | ||||
|     WII_IPC_WC24, | ||||
|     WII_IPC_SSL, | ||||
|     WII_IPC_SD, | ||||
|     WII_IPC_STM, | ||||
|     WII_IPC_WIIMOTE, | ||||
|     TIME, | ||||
|     NETPLAY, | ||||
| 
 | ||||
| 	NUMBER_OF_LOGS // Must be last
 | ||||
|     NUMBER_OF_LOGS // Must be last
 | ||||
| }; | ||||
| 
 | ||||
| // FIXME: should this be removed?
 | ||||
| enum LOG_LEVELS { | ||||
| 	LNOTICE = NOTICE_LEVEL, | ||||
| 	LERROR = ERROR_LEVEL, | ||||
| 	LWARNING = WARNING_LEVEL, | ||||
| 	LINFO = INFO_LEVEL, | ||||
| 	LDEBUG = DEBUG_LEVEL, | ||||
|     LNOTICE = NOTICE_LEVEL, | ||||
|     LERROR = ERROR_LEVEL, | ||||
|     LWARNING = WARNING_LEVEL, | ||||
|     LINFO = INFO_LEVEL, | ||||
|     LDEBUG = DEBUG_LEVEL, | ||||
| }; | ||||
| 
 | ||||
| #define LOGTYPES_LEVELS LogTypes::LOG_LEVELS | ||||
|  | @ -81,11 +81,11 @@ enum LOG_LEVELS { | |||
| }  // namespace
 | ||||
| 
 | ||||
| void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, | ||||
| 		const char *file, int line, const char *fmt, ...) | ||||
|         const char *file, int line, const char *fmt, ...) | ||||
| #ifdef __GNUC__ | ||||
| 		__attribute__((format(printf, 5, 6))) | ||||
|         __attribute__((format(printf, 5, 6))) | ||||
| #endif | ||||
| 		; | ||||
|         ; | ||||
| 
 | ||||
| #if defined LOGGING || defined _DEBUG || defined DEBUGFAST | ||||
| #define MAX_LOGLEVEL DEBUG_LEVEL | ||||
|  | @ -100,9 +100,9 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, | |||
| #else | ||||
| // Let the compiler optimize this out
 | ||||
| #define GENERIC_LOG(t, v, ...) { \ | ||||
| 	if (v <= MAX_LOGLEVEL) \ | ||||
| 		GenericLog(v, t, __FILE__, __LINE__, __VA_ARGS__); \ | ||||
| 	} | ||||
|     if (v <= MAX_LOGLEVEL) \ | ||||
|         GenericLog(v, t, __FILE__, __LINE__, __VA_ARGS__); \ | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
| #define ERROR_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LERROR, __VA_ARGS__) } while (0) | ||||
|  | @ -113,16 +113,16 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, | |||
| 
 | ||||
| #if MAX_LOGLEVEL >= DEBUG_LEVEL | ||||
| #define _dbg_assert_(_t_, _a_) \ | ||||
| 	if (!(_a_)) {\ | ||||
| 		ERROR_LOG(_t_, "Error...\n\n  Line: %d\n  File: %s\n  Time: %s\n\nIgnore and continue?", \ | ||||
| 					   __LINE__, __FILE__, __TIME__); \ | ||||
| 		if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \ | ||||
| 	} | ||||
|     if (!(_a_)) {\ | ||||
|         ERROR_LOG(_t_, "Error...\n\n  Line: %d\n  File: %s\n  Time: %s\n\nIgnore and continue?", \ | ||||
|                        __LINE__, __FILE__, __TIME__); \ | ||||
|         if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \ | ||||
|     } | ||||
| #define _dbg_assert_msg_(_t_, _a_, ...)\ | ||||
| 	if (!(_a_)) {\ | ||||
| 		ERROR_LOG(_t_, __VA_ARGS__); \ | ||||
| 		if (!PanicYesNo(__VA_ARGS__)) {Crash();} \ | ||||
| 	} | ||||
|     if (!(_a_)) {\ | ||||
|         ERROR_LOG(_t_, __VA_ARGS__); \ | ||||
|         if (!PanicYesNo(__VA_ARGS__)) {Crash();} \ | ||||
|     } | ||||
| #define _dbg_update_() Host_UpdateLogDisplay(); | ||||
| 
 | ||||
| #else // not debug
 | ||||
|  | @ -138,15 +138,15 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, | |||
| 
 | ||||
| #ifndef GEKKO | ||||
| #ifdef _WIN32 | ||||
| #define _assert_msg_(_t_, _a_, _fmt_, ...)		\ | ||||
| 	if (!(_a_)) {\ | ||||
| 		if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \ | ||||
| 	} | ||||
| #define _assert_msg_(_t_, _a_, _fmt_, ...)        \ | ||||
|     if (!(_a_)) {\ | ||||
|         if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \ | ||||
|     } | ||||
| #else // not win32
 | ||||
| #define _assert_msg_(_t_, _a_, _fmt_, ...)		\ | ||||
| 	if (!(_a_)) {\ | ||||
| 		if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \ | ||||
| 	} | ||||
| #define _assert_msg_(_t_, _a_, _fmt_, ...)        \ | ||||
|     if (!(_a_)) {\ | ||||
|         if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \ | ||||
|     } | ||||
| #endif // WIN32
 | ||||
| #else // GEKKO
 | ||||
| #define _assert_msg_(_t_, _a_, _fmt_, ...) | ||||
|  |  | |||
|  | @ -14,187 +14,187 @@ | |||
| #include "file_util.h" | ||||
| 
 | ||||
| void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,  | ||||
| 		const char *file, int line, const char* fmt, ...) | ||||
|         const char *file, int line, const char* fmt, ...) | ||||
| { | ||||
| 	va_list args; | ||||
| 	va_start(args, fmt); | ||||
| 	if (LogManager::GetInstance()) | ||||
| 		LogManager::GetInstance()->Log(level, type, | ||||
| 			file, line, fmt, args); | ||||
| 	va_end(args); | ||||
|     va_list args; | ||||
|     va_start(args, fmt); | ||||
|     if (LogManager::GetInstance()) | ||||
|         LogManager::GetInstance()->Log(level, type, | ||||
|             file, line, fmt, args); | ||||
|     va_end(args); | ||||
| } | ||||
| 
 | ||||
| LogManager *LogManager::m_logManager = NULL; | ||||
| 
 | ||||
| LogManager::LogManager() | ||||
| { | ||||
| 	// create log files
 | ||||
| 	m_Log[LogTypes::MASTER_LOG]			= new LogContainer("*",				"Master Log"); | ||||
| 	m_Log[LogTypes::BOOT]				= new LogContainer("BOOT",			"Boot"); | ||||
| 	m_Log[LogTypes::COMMON]				= new LogContainer("COMMON",		"Common"); | ||||
| 	m_Log[LogTypes::DISCIO]				= new LogContainer("DIO",			"Disc IO"); | ||||
| 	m_Log[LogTypes::FILEMON]			= new LogContainer("FileMon",		"File Monitor"); | ||||
| 	m_Log[LogTypes::PAD]				= new LogContainer("PAD",			"Pad"); | ||||
| 	m_Log[LogTypes::PIXELENGINE]		= new LogContainer("PE",			"PixelEngine"); | ||||
| 	m_Log[LogTypes::COMMANDPROCESSOR]	= new LogContainer("CP",			"CommandProc"); | ||||
| 	m_Log[LogTypes::VIDEOINTERFACE]		= new LogContainer("VI",			"VideoInt"); | ||||
| 	m_Log[LogTypes::SERIALINTERFACE]	= new LogContainer("SI",			"SerialInt"); | ||||
| 	m_Log[LogTypes::PROCESSORINTERFACE]	= new LogContainer("PI",			"ProcessorInt"); | ||||
| 	m_Log[LogTypes::MEMMAP]				= new LogContainer("MI",			"MI & memmap"); | ||||
| 	m_Log[LogTypes::SP1]				= new LogContainer("SP1",			"Serial Port 1"); | ||||
| 	m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream",		"StreamingInt"); | ||||
| 	m_Log[LogTypes::DSPINTERFACE]		= new LogContainer("DSP",			"DSPInterface"); | ||||
| 	m_Log[LogTypes::DVDINTERFACE]		= new LogContainer("DVD",			"DVDInterface"); | ||||
| 	m_Log[LogTypes::GPFIFO]				= new LogContainer("GP",			"GPFifo"); | ||||
| 	m_Log[LogTypes::EXPANSIONINTERFACE]	= new LogContainer("EXI",			"ExpansionInt"); | ||||
| 	m_Log[LogTypes::GDB_STUB]			= new LogContainer("GDB_STUB",		"GDB Stub"); | ||||
| 	m_Log[LogTypes::AUDIO_INTERFACE]	= new LogContainer("AI",			"AudioInt"); | ||||
| 	m_Log[LogTypes::ARM11]				= new LogContainer("ARM11",			"ARM11"); | ||||
| 	m_Log[LogTypes::OSHLE]				= new LogContainer("HLE",			"HLE"); | ||||
| 	m_Log[LogTypes::DSPHLE]				= new LogContainer("DSPHLE",		"DSP HLE"); | ||||
| 	m_Log[LogTypes::DSPLLE]				= new LogContainer("DSPLLE",		"DSP LLE"); | ||||
| 	m_Log[LogTypes::DSP_MAIL]			= new LogContainer("DSPMails",		"DSP Mails"); | ||||
| 	m_Log[LogTypes::VIDEO]				= new LogContainer("Video",			"Video Backend"); | ||||
| 	m_Log[LogTypes::AUDIO]				= new LogContainer("Audio",			"Audio Emulator"); | ||||
| 	m_Log[LogTypes::DYNA_REC]			= new LogContainer("JIT",			"Dynamic Recompiler"); | ||||
| 	m_Log[LogTypes::CONSOLE]			= new LogContainer("CONSOLE",		"Dolphin Console"); | ||||
| 	m_Log[LogTypes::OSREPORT]			= new LogContainer("OSREPORT",		"OSReport"); | ||||
| 	m_Log[LogTypes::TIME]				= new LogContainer("Time",			"Core Timing"); | ||||
| 	m_Log[LogTypes::LOADER]				= new LogContainer("Loader",		"Loader"); | ||||
| 	m_Log[LogTypes::FILESYS]			= new LogContainer("FileSys",		"File System"); | ||||
| 	m_Log[LogTypes::WII_IPC_HID]		= new LogContainer("WII_IPC_HID",	"WII IPC HID"); | ||||
| 	m_Log[LogTypes::WII_IPC_HLE]		= new LogContainer("WII_IPC_HLE",	"WII IPC HLE"); | ||||
| 	m_Log[LogTypes::WII_IPC_DVD]		= new LogContainer("WII_IPC_DVD",	"WII IPC DVD"); | ||||
| 	m_Log[LogTypes::WII_IPC_ES]			= new LogContainer("WII_IPC_ES",	"WII IPC ES"); | ||||
| 	m_Log[LogTypes::WII_IPC_FILEIO]		= new LogContainer("WII_IPC_FILEIO","WII IPC FILEIO"); | ||||
| 	m_Log[LogTypes::WII_IPC_SD]			= new LogContainer("WII_IPC_SD",	"WII IPC SD"); | ||||
| 	m_Log[LogTypes::WII_IPC_STM]		= new LogContainer("WII_IPC_STM",	"WII IPC STM"); | ||||
| 	m_Log[LogTypes::WII_IPC_NET]		= new LogContainer("WII_IPC_NET",	"WII IPC NET"); | ||||
| 	m_Log[LogTypes::WII_IPC_WC24]		= new LogContainer("WII_IPC_WC24",	"WII IPC WC24"); | ||||
| 	m_Log[LogTypes::WII_IPC_SSL]		= new LogContainer("WII_IPC_SSL",	"WII IPC SSL"); | ||||
| 	m_Log[LogTypes::WII_IPC_WIIMOTE]	= new LogContainer("WII_IPC_WIIMOTE","WII IPC WIIMOTE"); | ||||
| 	m_Log[LogTypes::ACTIONREPLAY]		= new LogContainer("ActionReplay",	"ActionReplay"); | ||||
| 	m_Log[LogTypes::MEMCARD_MANAGER]	= new LogContainer("MemCard Manager", "MemCard Manager"); | ||||
| 	m_Log[LogTypes::NETPLAY]			= new LogContainer("NETPLAY",		"Netplay"); | ||||
|     // create log files
 | ||||
|     m_Log[LogTypes::MASTER_LOG]            = new LogContainer("*",                "Master Log"); | ||||
|     m_Log[LogTypes::BOOT]                = new LogContainer("BOOT",            "Boot"); | ||||
|     m_Log[LogTypes::COMMON]                = new LogContainer("COMMON",        "Common"); | ||||
|     m_Log[LogTypes::DISCIO]                = new LogContainer("DIO",            "Disc IO"); | ||||
|     m_Log[LogTypes::FILEMON]            = new LogContainer("FileMon",        "File Monitor"); | ||||
|     m_Log[LogTypes::PAD]                = new LogContainer("PAD",            "Pad"); | ||||
|     m_Log[LogTypes::PIXELENGINE]        = new LogContainer("PE",            "PixelEngine"); | ||||
|     m_Log[LogTypes::COMMANDPROCESSOR]    = new LogContainer("CP",            "CommandProc"); | ||||
|     m_Log[LogTypes::VIDEOINTERFACE]        = new LogContainer("VI",            "VideoInt"); | ||||
|     m_Log[LogTypes::SERIALINTERFACE]    = new LogContainer("SI",            "SerialInt"); | ||||
|     m_Log[LogTypes::PROCESSORINTERFACE]    = new LogContainer("PI",            "ProcessorInt"); | ||||
|     m_Log[LogTypes::MEMMAP]                = new LogContainer("MI",            "MI & memmap"); | ||||
|     m_Log[LogTypes::SP1]                = new LogContainer("SP1",            "Serial Port 1"); | ||||
|     m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream",        "StreamingInt"); | ||||
|     m_Log[LogTypes::DSPINTERFACE]        = new LogContainer("DSP",            "DSPInterface"); | ||||
|     m_Log[LogTypes::DVDINTERFACE]        = new LogContainer("DVD",            "DVDInterface"); | ||||
|     m_Log[LogTypes::GPFIFO]                = new LogContainer("GP",            "GPFifo"); | ||||
|     m_Log[LogTypes::EXPANSIONINTERFACE]    = new LogContainer("EXI",            "ExpansionInt"); | ||||
|     m_Log[LogTypes::GDB_STUB]            = new LogContainer("GDB_STUB",        "GDB Stub"); | ||||
|     m_Log[LogTypes::AUDIO_INTERFACE]    = new LogContainer("AI",            "AudioInt"); | ||||
|     m_Log[LogTypes::ARM11]                = new LogContainer("ARM11",            "ARM11"); | ||||
|     m_Log[LogTypes::OSHLE]                = new LogContainer("HLE",            "HLE"); | ||||
|     m_Log[LogTypes::DSPHLE]                = new LogContainer("DSPHLE",        "DSP HLE"); | ||||
|     m_Log[LogTypes::DSPLLE]                = new LogContainer("DSPLLE",        "DSP LLE"); | ||||
|     m_Log[LogTypes::DSP_MAIL]            = new LogContainer("DSPMails",        "DSP Mails"); | ||||
|     m_Log[LogTypes::VIDEO]                = new LogContainer("Video",            "Video Backend"); | ||||
|     m_Log[LogTypes::AUDIO]                = new LogContainer("Audio",            "Audio Emulator"); | ||||
|     m_Log[LogTypes::DYNA_REC]            = new LogContainer("JIT",            "Dynamic Recompiler"); | ||||
|     m_Log[LogTypes::CONSOLE]            = new LogContainer("CONSOLE",        "Dolphin Console"); | ||||
|     m_Log[LogTypes::OSREPORT]            = new LogContainer("OSREPORT",        "OSReport"); | ||||
|     m_Log[LogTypes::TIME]                = new LogContainer("Time",            "Core Timing"); | ||||
|     m_Log[LogTypes::LOADER]                = new LogContainer("Loader",        "Loader"); | ||||
|     m_Log[LogTypes::FILESYS]            = new LogContainer("FileSys",        "File System"); | ||||
|     m_Log[LogTypes::WII_IPC_HID]        = new LogContainer("WII_IPC_HID",    "WII IPC HID"); | ||||
|     m_Log[LogTypes::WII_IPC_HLE]        = new LogContainer("WII_IPC_HLE",    "WII IPC HLE"); | ||||
|     m_Log[LogTypes::WII_IPC_DVD]        = new LogContainer("WII_IPC_DVD",    "WII IPC DVD"); | ||||
|     m_Log[LogTypes::WII_IPC_ES]            = new LogContainer("WII_IPC_ES",    "WII IPC ES"); | ||||
|     m_Log[LogTypes::WII_IPC_FILEIO]        = new LogContainer("WII_IPC_FILEIO","WII IPC FILEIO"); | ||||
|     m_Log[LogTypes::WII_IPC_SD]            = new LogContainer("WII_IPC_SD",    "WII IPC SD"); | ||||
|     m_Log[LogTypes::WII_IPC_STM]        = new LogContainer("WII_IPC_STM",    "WII IPC STM"); | ||||
|     m_Log[LogTypes::WII_IPC_NET]        = new LogContainer("WII_IPC_NET",    "WII IPC NET"); | ||||
|     m_Log[LogTypes::WII_IPC_WC24]        = new LogContainer("WII_IPC_WC24",    "WII IPC WC24"); | ||||
|     m_Log[LogTypes::WII_IPC_SSL]        = new LogContainer("WII_IPC_SSL",    "WII IPC SSL"); | ||||
|     m_Log[LogTypes::WII_IPC_WIIMOTE]    = new LogContainer("WII_IPC_WIIMOTE","WII IPC WIIMOTE"); | ||||
|     m_Log[LogTypes::ACTIONREPLAY]        = new LogContainer("ActionReplay",    "ActionReplay"); | ||||
|     m_Log[LogTypes::MEMCARD_MANAGER]    = new LogContainer("MemCard Manager", "MemCard Manager"); | ||||
|     m_Log[LogTypes::NETPLAY]            = new LogContainer("NETPLAY",        "Netplay"); | ||||
| 
 | ||||
| 	m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str()); | ||||
| 	m_consoleLog = new ConsoleListener(); | ||||
| 	m_debuggerLog = new DebuggerLogListener(); | ||||
|     m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str()); | ||||
|     m_consoleLog = new ConsoleListener(); | ||||
|     m_debuggerLog = new DebuggerLogListener(); | ||||
| 
 | ||||
| 	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | ||||
| 	{ | ||||
| 		m_Log[i]->SetEnable(true); | ||||
| 		m_Log[i]->AddListener(m_fileLog); | ||||
| 		m_Log[i]->AddListener(m_consoleLog); | ||||
|     for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | ||||
|     { | ||||
|         m_Log[i]->SetEnable(true); | ||||
|         m_Log[i]->AddListener(m_fileLog); | ||||
|         m_Log[i]->AddListener(m_consoleLog); | ||||
| #ifdef _MSC_VER | ||||
| 		if (IsDebuggerPresent()) | ||||
| 			m_Log[i]->AddListener(m_debuggerLog); | ||||
|         if (IsDebuggerPresent()) | ||||
|             m_Log[i]->AddListener(m_debuggerLog); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| LogManager::~LogManager() | ||||
| { | ||||
| 	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | ||||
| 	{ | ||||
| 		m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_fileLog); | ||||
| 		m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog); | ||||
| 		m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_debuggerLog); | ||||
| 	} | ||||
|     for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | ||||
|     { | ||||
|         m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_fileLog); | ||||
|         m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog); | ||||
|         m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_debuggerLog); | ||||
|     } | ||||
| 
 | ||||
| 	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | ||||
| 		delete m_Log[i]; | ||||
|     for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | ||||
|         delete m_Log[i]; | ||||
| 
 | ||||
| 	delete m_fileLog; | ||||
| 	delete m_consoleLog; | ||||
| 	delete m_debuggerLog; | ||||
|     delete m_fileLog; | ||||
|     delete m_consoleLog; | ||||
|     delete m_debuggerLog; | ||||
| } | ||||
| 
 | ||||
| void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,  | ||||
| 	const char *file, int line, const char *format, va_list args) | ||||
|     const char *file, int line, const char *format, va_list args) | ||||
| { | ||||
| 	char temp[MAX_MSGLEN]; | ||||
| 	char msg[MAX_MSGLEN * 2]; | ||||
| 	LogContainer *log = m_Log[type]; | ||||
|     char temp[MAX_MSGLEN]; | ||||
|     char msg[MAX_MSGLEN * 2]; | ||||
|     LogContainer *log = m_Log[type]; | ||||
| 
 | ||||
| 	if (!log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners()) | ||||
| 		return; | ||||
|     if (!log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners()) | ||||
|         return; | ||||
| 
 | ||||
| 	CharArrayFromFormatV(temp, MAX_MSGLEN, format, args); | ||||
|     CharArrayFromFormatV(temp, MAX_MSGLEN, format, args); | ||||
| 
 | ||||
| 	static const char level_to_char[7] = "-NEWID"; | ||||
| 	sprintf(msg, "%s %s:%u %c[%s]: %s\n", | ||||
| 		Common::Timer::GetTimeFormatted().c_str(), | ||||
| 		file, line, level_to_char[(int)level], | ||||
| 		log->GetShortName(), temp); | ||||
|     static const char level_to_char[7] = "-NEWID"; | ||||
|     sprintf(msg, "%s %s:%u %c[%s]: %s\n", | ||||
|         Common::Timer::GetTimeFormatted().c_str(), | ||||
|         file, line, level_to_char[(int)level], | ||||
|         log->GetShortName(), temp); | ||||
| #ifdef ANDROID | ||||
| 	Host_SysMessage(msg);	 | ||||
|     Host_SysMessage(msg);     | ||||
| #endif | ||||
| 	printf(msg); // TODO(ShizZy): RemoveMe when I no longer need this
 | ||||
| 	log->Trigger(level, msg); | ||||
|     printf(msg); // TODO(ShizZy): RemoveMe when I no longer need this
 | ||||
|     log->Trigger(level, msg); | ||||
| } | ||||
| 
 | ||||
| void LogManager::Init() | ||||
| { | ||||
| 	m_logManager = new LogManager(); | ||||
|     m_logManager = new LogManager(); | ||||
| } | ||||
| 
 | ||||
| void LogManager::Shutdown() | ||||
| { | ||||
| 	delete m_logManager; | ||||
| 	m_logManager = NULL; | ||||
|     delete m_logManager; | ||||
|     m_logManager = NULL; | ||||
| } | ||||
| 
 | ||||
| LogContainer::LogContainer(const char* shortName, const char* fullName, bool enable) | ||||
| 	: m_enable(enable) | ||||
|     : m_enable(enable) | ||||
| { | ||||
| 	strncpy(m_fullName, fullName, 128); | ||||
| 	strncpy(m_shortName, shortName, 32); | ||||
| 	m_level = LogTypes::LWARNING; | ||||
|     strncpy(m_fullName, fullName, 128); | ||||
|     strncpy(m_shortName, shortName, 32); | ||||
|     m_level = LogTypes::LWARNING; | ||||
| } | ||||
| 
 | ||||
| // LogContainer
 | ||||
| void LogContainer::AddListener(LogListener *listener) | ||||
| { | ||||
| 	std::lock_guard<std::mutex> lk(m_listeners_lock); | ||||
| 	m_listeners.insert(listener); | ||||
|     std::lock_guard<std::mutex> lk(m_listeners_lock); | ||||
|     m_listeners.insert(listener); | ||||
| } | ||||
| 
 | ||||
| void LogContainer::RemoveListener(LogListener *listener) | ||||
| { | ||||
| 	std::lock_guard<std::mutex> lk(m_listeners_lock); | ||||
| 	m_listeners.erase(listener); | ||||
|     std::lock_guard<std::mutex> lk(m_listeners_lock); | ||||
|     m_listeners.erase(listener); | ||||
| } | ||||
| 
 | ||||
| void LogContainer::Trigger(LogTypes::LOG_LEVELS level, const char *msg) | ||||
| { | ||||
| 	std::lock_guard<std::mutex> lk(m_listeners_lock); | ||||
|     std::lock_guard<std::mutex> lk(m_listeners_lock); | ||||
| 
 | ||||
| 	std::set<LogListener*>::const_iterator i; | ||||
| 	for (i = m_listeners.begin(); i != m_listeners.end(); ++i) | ||||
| 	{ | ||||
| 		(*i)->Log(level, msg); | ||||
| 	} | ||||
|     std::set<LogListener*>::const_iterator i; | ||||
|     for (i = m_listeners.begin(); i != m_listeners.end(); ++i) | ||||
|     { | ||||
|         (*i)->Log(level, msg); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| FileLogListener::FileLogListener(const char *filename) | ||||
| { | ||||
| 	OpenFStream(m_logfile, filename, std::ios::app); | ||||
| 	SetEnable(true); | ||||
|     OpenFStream(m_logfile, filename, std::ios::app); | ||||
|     SetEnable(true); | ||||
| } | ||||
| 
 | ||||
| void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) | ||||
| { | ||||
| 	if (!IsEnabled() || !IsValid()) | ||||
| 		return; | ||||
|     if (!IsEnabled() || !IsValid()) | ||||
|         return; | ||||
| 
 | ||||
| 	std::lock_guard<std::mutex> lk(m_log_lock); | ||||
| 	m_logfile << msg << std::flush; | ||||
|     std::lock_guard<std::mutex> lk(m_log_lock); | ||||
|     m_logfile << msg << std::flush; | ||||
| } | ||||
| 
 | ||||
| void DebuggerLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) | ||||
| { | ||||
| #if _MSC_VER | ||||
| 	::OutputDebugStringA(msg); | ||||
|     ::OutputDebugStringA(msg); | ||||
| #endif | ||||
| } | ||||
|  |  | |||
|  | @ -21,65 +21,65 @@ | |||
| class LogListener | ||||
| { | ||||
| public: | ||||
| 	virtual ~LogListener() {} | ||||
|     virtual ~LogListener() {} | ||||
| 
 | ||||
| 	virtual void Log(LogTypes::LOG_LEVELS, const char *msg) = 0; | ||||
|     virtual void Log(LogTypes::LOG_LEVELS, const char *msg) = 0; | ||||
| }; | ||||
| 
 | ||||
| class FileLogListener : public LogListener | ||||
| { | ||||
| public: | ||||
| 	FileLogListener(const char *filename); | ||||
|     FileLogListener(const char *filename); | ||||
| 
 | ||||
| 	void Log(LogTypes::LOG_LEVELS, const char *msg); | ||||
|     void Log(LogTypes::LOG_LEVELS, const char *msg); | ||||
| 
 | ||||
| 	bool IsValid() { return !m_logfile.fail(); } | ||||
| 	bool IsEnabled() const { return m_enable; } | ||||
| 	void SetEnable(bool enable) { m_enable = enable; } | ||||
|     bool IsValid() { return !m_logfile.fail(); } | ||||
|     bool IsEnabled() const { return m_enable; } | ||||
|     void SetEnable(bool enable) { m_enable = enable; } | ||||
| 
 | ||||
| 	const char* GetName() const { return "file"; } | ||||
|     const char* GetName() const { return "file"; } | ||||
| 
 | ||||
| private: | ||||
| 	std::mutex m_log_lock; | ||||
| 	std::ofstream m_logfile; | ||||
| 	bool m_enable; | ||||
|     std::mutex m_log_lock; | ||||
|     std::ofstream m_logfile; | ||||
|     bool m_enable; | ||||
| }; | ||||
| 
 | ||||
| class DebuggerLogListener : public LogListener | ||||
| { | ||||
| public: | ||||
| 	void Log(LogTypes::LOG_LEVELS, const char *msg); | ||||
|     void Log(LogTypes::LOG_LEVELS, const char *msg); | ||||
| }; | ||||
| 
 | ||||
| class LogContainer | ||||
| { | ||||
| public: | ||||
| 	LogContainer(const char* shortName, const char* fullName, bool enable = false); | ||||
| 	 | ||||
| 	const char* GetShortName() const { return m_shortName; } | ||||
| 	const char* GetFullName() const { return m_fullName; } | ||||
|     LogContainer(const char* shortName, const char* fullName, bool enable = false); | ||||
|      | ||||
|     const char* GetShortName() const { return m_shortName; } | ||||
|     const char* GetFullName() const { return m_fullName; } | ||||
| 
 | ||||
| 	void AddListener(LogListener* listener); | ||||
| 	void RemoveListener(LogListener* listener); | ||||
|     void AddListener(LogListener* listener); | ||||
|     void RemoveListener(LogListener* listener); | ||||
| 
 | ||||
| 	void Trigger(LogTypes::LOG_LEVELS, const char *msg); | ||||
|     void Trigger(LogTypes::LOG_LEVELS, const char *msg); | ||||
| 
 | ||||
| 	bool IsEnabled() const { return m_enable; } | ||||
| 	void SetEnable(bool enable) { m_enable = enable; } | ||||
|     bool IsEnabled() const { return m_enable; } | ||||
|     void SetEnable(bool enable) { m_enable = enable; } | ||||
| 
 | ||||
| 	LogTypes::LOG_LEVELS GetLevel() const { return m_level;	} | ||||
|     LogTypes::LOG_LEVELS GetLevel() const { return m_level;    } | ||||
| 
 | ||||
| 	void SetLevel(LogTypes::LOG_LEVELS level) {	m_level = level; } | ||||
|     void SetLevel(LogTypes::LOG_LEVELS level) {    m_level = level; } | ||||
| 
 | ||||
| 	bool HasListeners() const { return !m_listeners.empty(); } | ||||
|     bool HasListeners() const { return !m_listeners.empty(); } | ||||
| 
 | ||||
| private: | ||||
| 	char m_fullName[128]; | ||||
| 	char m_shortName[32]; | ||||
| 	bool m_enable; | ||||
| 	LogTypes::LOG_LEVELS m_level; | ||||
| 	std::mutex m_listeners_lock; | ||||
| 	std::set<LogListener*> m_listeners; | ||||
|     char m_fullName[128]; | ||||
|     char m_shortName[32]; | ||||
|     bool m_enable; | ||||
|     LogTypes::LOG_LEVELS m_level; | ||||
|     std::mutex m_listeners_lock; | ||||
|     std::set<LogListener*> m_listeners; | ||||
| }; | ||||
| 
 | ||||
| class ConsoleListener; | ||||
|  | @ -87,83 +87,83 @@ class ConsoleListener; | |||
| class LogManager : NonCopyable | ||||
| { | ||||
| private: | ||||
| 	LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS]; | ||||
| 	FileLogListener *m_fileLog; | ||||
| 	ConsoleListener *m_consoleLog; | ||||
| 	DebuggerLogListener *m_debuggerLog; | ||||
| 	static LogManager *m_logManager;  // Singleton. Ugh.
 | ||||
|     LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS]; | ||||
|     FileLogListener *m_fileLog; | ||||
|     ConsoleListener *m_consoleLog; | ||||
|     DebuggerLogListener *m_debuggerLog; | ||||
|     static LogManager *m_logManager;  // Singleton. Ugh.
 | ||||
| 
 | ||||
| 	LogManager(); | ||||
| 	~LogManager(); | ||||
|     LogManager(); | ||||
|     ~LogManager(); | ||||
| public: | ||||
| 
 | ||||
| 	static u32 GetMaxLevel() { return MAX_LOGLEVEL;	} | ||||
|     static u32 GetMaxLevel() { return MAX_LOGLEVEL;    } | ||||
| 
 | ||||
| 	void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,  | ||||
| 			 const char *file, int line, const char *fmt, va_list args); | ||||
|     void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,  | ||||
|              const char *file, int line, const char *fmt, va_list args); | ||||
| 
 | ||||
| 	void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level) | ||||
| 	{ | ||||
| 		m_Log[type]->SetLevel(level); | ||||
| 	} | ||||
|     void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level) | ||||
|     { | ||||
|         m_Log[type]->SetLevel(level); | ||||
|     } | ||||
| 
 | ||||
| 	void SetEnable(LogTypes::LOG_TYPE type, bool enable) | ||||
| 	{ | ||||
| 		m_Log[type]->SetEnable(enable); | ||||
| 	} | ||||
|     void SetEnable(LogTypes::LOG_TYPE type, bool enable) | ||||
|     { | ||||
|         m_Log[type]->SetEnable(enable); | ||||
|     } | ||||
| 
 | ||||
| 	bool IsEnabled(LogTypes::LOG_TYPE type) const | ||||
| 	{ | ||||
| 		return m_Log[type]->IsEnabled(); | ||||
| 	} | ||||
|     bool IsEnabled(LogTypes::LOG_TYPE type) const | ||||
|     { | ||||
|         return m_Log[type]->IsEnabled(); | ||||
|     } | ||||
| 
 | ||||
| 	const char* GetShortName(LogTypes::LOG_TYPE type) const | ||||
| 	{ | ||||
| 		return m_Log[type]->GetShortName(); | ||||
| 	} | ||||
|     const char* GetShortName(LogTypes::LOG_TYPE type) const | ||||
|     { | ||||
|         return m_Log[type]->GetShortName(); | ||||
|     } | ||||
| 
 | ||||
| 	const char* GetFullName(LogTypes::LOG_TYPE type) const | ||||
| 	{ | ||||
| 		return m_Log[type]->GetFullName(); | ||||
| 	} | ||||
|     const char* GetFullName(LogTypes::LOG_TYPE type) const | ||||
|     { | ||||
|         return m_Log[type]->GetFullName(); | ||||
|     } | ||||
| 
 | ||||
| 	void AddListener(LogTypes::LOG_TYPE type, LogListener *listener) | ||||
| 	{ | ||||
| 		m_Log[type]->AddListener(listener); | ||||
| 	} | ||||
|     void AddListener(LogTypes::LOG_TYPE type, LogListener *listener) | ||||
|     { | ||||
|         m_Log[type]->AddListener(listener); | ||||
|     } | ||||
| 
 | ||||
| 	void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener) | ||||
| 	{ | ||||
| 		m_Log[type]->RemoveListener(listener); | ||||
| 	} | ||||
|     void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener) | ||||
|     { | ||||
|         m_Log[type]->RemoveListener(listener); | ||||
|     } | ||||
| 
 | ||||
| 	FileLogListener *GetFileListener() const | ||||
| 	{ | ||||
| 		return m_fileLog; | ||||
| 	} | ||||
|     FileLogListener *GetFileListener() const | ||||
|     { | ||||
|         return m_fileLog; | ||||
|     } | ||||
| 
 | ||||
| 	ConsoleListener *GetConsoleListener() const | ||||
| 	{ | ||||
| 		return m_consoleLog; | ||||
| 	} | ||||
|     ConsoleListener *GetConsoleListener() const | ||||
|     { | ||||
|         return m_consoleLog; | ||||
|     } | ||||
| 
 | ||||
| 	DebuggerLogListener *GetDebuggerListener() const | ||||
| 	{ | ||||
| 		return m_debuggerLog; | ||||
| 	} | ||||
|     DebuggerLogListener *GetDebuggerListener() const | ||||
|     { | ||||
|         return m_debuggerLog; | ||||
|     } | ||||
| 
 | ||||
| 	static LogManager* GetInstance() | ||||
| 	{ | ||||
| 		return m_logManager; | ||||
| 	} | ||||
|     static LogManager* GetInstance() | ||||
|     { | ||||
|         return m_logManager; | ||||
|     } | ||||
| 
 | ||||
| 	static void SetInstance(LogManager *logManager) | ||||
| 	{ | ||||
| 		m_logManager = logManager; | ||||
| 	} | ||||
|     static void SetInstance(LogManager *logManager) | ||||
|     { | ||||
|         m_logManager = logManager; | ||||
|     } | ||||
| 
 | ||||
| 	static void Init(); | ||||
| 	static void Shutdown(); | ||||
|     static void Init(); | ||||
|     static void Shutdown(); | ||||
| }; | ||||
| 
 | ||||
| #endif // _LOGMANAGER_H_
 | ||||
|  |  | |||
|  | @ -14,82 +14,82 @@ namespace MathUtil | |||
| 
 | ||||
| u32 ClassifyDouble(double dvalue) | ||||
| { | ||||
| 	// TODO: Optimize the below to be as fast as possible.
 | ||||
| 	IntDouble value; | ||||
| 	value.d = dvalue; | ||||
| 	u64 sign = value.i & DOUBLE_SIGN; | ||||
| 	u64 exp  = value.i & DOUBLE_EXP; | ||||
| 	if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP)  | ||||
| 	{ | ||||
| 		// Nice normalized number.
 | ||||
| 		return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		u64 mantissa = value.i & DOUBLE_FRAC; | ||||
| 		if (mantissa) | ||||
| 		{ | ||||
| 			if (exp) | ||||
| 			{ | ||||
| 				return PPC_FPCLASS_QNAN; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				// Denormalized number.
 | ||||
| 				return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; | ||||
| 			} | ||||
| 		} | ||||
| 		else if (exp) | ||||
| 		{ | ||||
| 			//Infinite
 | ||||
| 			return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			//Zero
 | ||||
| 			return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; | ||||
| 		} | ||||
| 	} | ||||
|     // TODO: Optimize the below to be as fast as possible.
 | ||||
|     IntDouble value; | ||||
|     value.d = dvalue; | ||||
|     u64 sign = value.i & DOUBLE_SIGN; | ||||
|     u64 exp  = value.i & DOUBLE_EXP; | ||||
|     if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP)  | ||||
|     { | ||||
|         // Nice normalized number.
 | ||||
|         return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         u64 mantissa = value.i & DOUBLE_FRAC; | ||||
|         if (mantissa) | ||||
|         { | ||||
|             if (exp) | ||||
|             { | ||||
|                 return PPC_FPCLASS_QNAN; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 // Denormalized number.
 | ||||
|                 return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; | ||||
|             } | ||||
|         } | ||||
|         else if (exp) | ||||
|         { | ||||
|             //Infinite
 | ||||
|             return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             //Zero
 | ||||
|             return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| u32 ClassifyFloat(float fvalue) | ||||
| { | ||||
| 	// TODO: Optimize the below to be as fast as possible.
 | ||||
| 	IntFloat value; | ||||
| 	value.f = fvalue; | ||||
| 	u32 sign = value.i & FLOAT_SIGN; | ||||
| 	u32 exp  = value.i & FLOAT_EXP; | ||||
| 	if (exp > FLOAT_ZERO && exp < FLOAT_EXP)  | ||||
| 	{ | ||||
| 		// Nice normalized number.
 | ||||
| 		return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		u32 mantissa = value.i & FLOAT_FRAC; | ||||
| 		if (mantissa) | ||||
| 		{ | ||||
| 			if (exp) | ||||
| 			{ | ||||
| 				return PPC_FPCLASS_QNAN; // Quiet NAN
 | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				// Denormalized number.
 | ||||
| 				return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; | ||||
| 			} | ||||
| 		}  | ||||
| 		else if (exp)  | ||||
| 		{ | ||||
| 			// Infinite
 | ||||
| 			return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; | ||||
| 		}  | ||||
| 		else  | ||||
| 		{ | ||||
| 			//Zero
 | ||||
| 			return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; | ||||
| 		} | ||||
| 	} | ||||
|     // TODO: Optimize the below to be as fast as possible.
 | ||||
|     IntFloat value; | ||||
|     value.f = fvalue; | ||||
|     u32 sign = value.i & FLOAT_SIGN; | ||||
|     u32 exp  = value.i & FLOAT_EXP; | ||||
|     if (exp > FLOAT_ZERO && exp < FLOAT_EXP)  | ||||
|     { | ||||
|         // Nice normalized number.
 | ||||
|         return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         u32 mantissa = value.i & FLOAT_FRAC; | ||||
|         if (mantissa) | ||||
|         { | ||||
|             if (exp) | ||||
|             { | ||||
|                 return PPC_FPCLASS_QNAN; // Quiet NAN
 | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 // Denormalized number.
 | ||||
|                 return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; | ||||
|             } | ||||
|         }  | ||||
|         else if (exp)  | ||||
|         { | ||||
|             // Infinite
 | ||||
|             return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; | ||||
|         }  | ||||
|         else  | ||||
|         { | ||||
|             //Zero
 | ||||
|             return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -97,116 +97,116 @@ u32 ClassifyFloat(float fvalue) | |||
| 
 | ||||
| inline void MatrixMul(int n, const float *a, const float *b, float *result) | ||||
| { | ||||
| 	for (int i = 0; i < n; ++i) | ||||
| 	{ | ||||
| 		for (int j = 0; j < n; ++j) | ||||
| 		{ | ||||
| 			float temp = 0; | ||||
| 			for (int k = 0; k < n; ++k) | ||||
| 			{ | ||||
| 				temp += a[i * n + k] * b[k * n + j]; | ||||
| 			} | ||||
| 			result[i * n + j] = temp; | ||||
| 		} | ||||
| 	} | ||||
|     for (int i = 0; i < n; ++i) | ||||
|     { | ||||
|         for (int j = 0; j < n; ++j) | ||||
|         { | ||||
|             float temp = 0; | ||||
|             for (int k = 0; k < n; ++k) | ||||
|             { | ||||
|                 temp += a[i * n + k] * b[k * n + j]; | ||||
|             } | ||||
|             result[i * n + j] = temp; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Calculate sum of a float list
 | ||||
| float MathFloatVectorSum(const std::vector<float>& Vec) | ||||
| { | ||||
| 	return std::accumulate(Vec.begin(), Vec.end(), 0.0f); | ||||
|     return std::accumulate(Vec.begin(), Vec.end(), 0.0f); | ||||
| } | ||||
| 
 | ||||
| void Matrix33::LoadIdentity(Matrix33 &mtx) | ||||
| { | ||||
| 	memset(mtx.data, 0, sizeof(mtx.data)); | ||||
| 	mtx.data[0] = 1.0f; | ||||
| 	mtx.data[4] = 1.0f; | ||||
| 	mtx.data[8] = 1.0f; | ||||
|     memset(mtx.data, 0, sizeof(mtx.data)); | ||||
|     mtx.data[0] = 1.0f; | ||||
|     mtx.data[4] = 1.0f; | ||||
|     mtx.data[8] = 1.0f; | ||||
| } | ||||
| 
 | ||||
| void Matrix33::RotateX(Matrix33 &mtx, float rad) | ||||
| { | ||||
| 	float s = sin(rad); | ||||
| 	float c = cos(rad); | ||||
| 	memset(mtx.data, 0, sizeof(mtx.data)); | ||||
| 	mtx.data[0] = 1; | ||||
| 	mtx.data[4] = c; | ||||
| 	mtx.data[5] = -s; | ||||
| 	mtx.data[7] = s; | ||||
| 	mtx.data[8] = c; | ||||
|     float s = sin(rad); | ||||
|     float c = cos(rad); | ||||
|     memset(mtx.data, 0, sizeof(mtx.data)); | ||||
|     mtx.data[0] = 1; | ||||
|     mtx.data[4] = c; | ||||
|     mtx.data[5] = -s; | ||||
|     mtx.data[7] = s; | ||||
|     mtx.data[8] = c; | ||||
| } | ||||
| void Matrix33::RotateY(Matrix33 &mtx, float rad) | ||||
| { | ||||
| 	float s = sin(rad); | ||||
| 	float c = cos(rad); | ||||
| 	memset(mtx.data, 0, sizeof(mtx.data)); | ||||
| 	mtx.data[0] = c; | ||||
| 	mtx.data[2] = s; | ||||
| 	mtx.data[4] = 1; | ||||
| 	mtx.data[6] = -s;     | ||||
| 	mtx.data[8] = c; | ||||
|     float s = sin(rad); | ||||
|     float c = cos(rad); | ||||
|     memset(mtx.data, 0, sizeof(mtx.data)); | ||||
|     mtx.data[0] = c; | ||||
|     mtx.data[2] = s; | ||||
|     mtx.data[4] = 1; | ||||
|     mtx.data[6] = -s;     | ||||
|     mtx.data[8] = c; | ||||
| } | ||||
| 
 | ||||
| void Matrix33::Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result) | ||||
| { | ||||
| 	MatrixMul(3, a.data, b.data, result.data); | ||||
|     MatrixMul(3, a.data, b.data, result.data); | ||||
| } | ||||
| 
 | ||||
| void Matrix33::Multiply(const Matrix33 &a, const float vec[3], float result[3]) | ||||
| { | ||||
| 	for (int i = 0; i < 3; ++i) { | ||||
| 		result[i] = 0; | ||||
| 		for (int k = 0; k < 3; ++k) { | ||||
| 			result[i] += a.data[i * 3 + k] * vec[k]; | ||||
| 		} | ||||
| 	} | ||||
|     for (int i = 0; i < 3; ++i) { | ||||
|         result[i] = 0; | ||||
|         for (int k = 0; k < 3; ++k) { | ||||
|             result[i] += a.data[i * 3 + k] * vec[k]; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Matrix44::LoadIdentity(Matrix44 &mtx) | ||||
| { | ||||
| 	memset(mtx.data, 0, sizeof(mtx.data)); | ||||
| 	mtx.data[0] = 1.0f; | ||||
| 	mtx.data[5] = 1.0f; | ||||
| 	mtx.data[10] = 1.0f; | ||||
| 	mtx.data[15] = 1.0f; | ||||
|     memset(mtx.data, 0, sizeof(mtx.data)); | ||||
|     mtx.data[0] = 1.0f; | ||||
|     mtx.data[5] = 1.0f; | ||||
|     mtx.data[10] = 1.0f; | ||||
|     mtx.data[15] = 1.0f; | ||||
| } | ||||
| 
 | ||||
| void Matrix44::LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33) | ||||
| { | ||||
| 	for (int i = 0; i < 3; ++i) | ||||
| 	{ | ||||
| 		for (int j = 0; j < 3; ++j) | ||||
| 		{ | ||||
| 			mtx.data[i * 4 + j] = m33.data[i * 3 + j]; | ||||
| 		} | ||||
| 	} | ||||
|     for (int i = 0; i < 3; ++i) | ||||
|     { | ||||
|         for (int j = 0; j < 3; ++j) | ||||
|         { | ||||
|             mtx.data[i * 4 + j] = m33.data[i * 3 + j]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	for (int i = 0; i < 3; ++i) | ||||
| 	{ | ||||
| 		mtx.data[i * 4 + 3] = 0; | ||||
| 		mtx.data[i + 12] = 0; | ||||
| 	} | ||||
| 	mtx.data[15] = 1.0f; | ||||
|     for (int i = 0; i < 3; ++i) | ||||
|     { | ||||
|         mtx.data[i * 4 + 3] = 0; | ||||
|         mtx.data[i + 12] = 0; | ||||
|     } | ||||
|     mtx.data[15] = 1.0f; | ||||
| } | ||||
| 
 | ||||
| void Matrix44::Set(Matrix44 &mtx, const float mtxArray[16]) | ||||
| { | ||||
| 	for(int i = 0; i < 16; ++i) { | ||||
| 		mtx.data[i] = mtxArray[i]; | ||||
| 	} | ||||
|     for(int i = 0; i < 16; ++i) { | ||||
|         mtx.data[i] = mtxArray[i]; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Matrix44::Translate(Matrix44 &mtx, const float vec[3]) | ||||
| { | ||||
| 	LoadIdentity(mtx); | ||||
| 	mtx.data[3] = vec[0]; | ||||
| 	mtx.data[7] = vec[1]; | ||||
| 	mtx.data[11] = vec[2]; | ||||
|     LoadIdentity(mtx); | ||||
|     mtx.data[3] = vec[0]; | ||||
|     mtx.data[7] = vec[1]; | ||||
|     mtx.data[11] = vec[2]; | ||||
| } | ||||
| 
 | ||||
| void Matrix44::Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result) | ||||
| { | ||||
| 	MatrixMul(4, a.data, b.data, result.data); | ||||
|     MatrixMul(4, a.data, b.data, result.data); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,74 +14,74 @@ namespace MathUtil | |||
| { | ||||
| 
 | ||||
| static const u64 DOUBLE_SIGN = 0x8000000000000000ULL, | ||||
| 	DOUBLE_EXP  = 0x7FF0000000000000ULL, | ||||
| 	DOUBLE_FRAC = 0x000FFFFFFFFFFFFFULL, | ||||
| 	DOUBLE_ZERO = 0x0000000000000000ULL; | ||||
|     DOUBLE_EXP  = 0x7FF0000000000000ULL, | ||||
|     DOUBLE_FRAC = 0x000FFFFFFFFFFFFFULL, | ||||
|     DOUBLE_ZERO = 0x0000000000000000ULL; | ||||
| 
 | ||||
| static const u32 FLOAT_SIGN = 0x80000000, | ||||
| 	FLOAT_EXP  = 0x7F800000, | ||||
| 	FLOAT_FRAC = 0x007FFFFF, | ||||
| 	FLOAT_ZERO = 0x00000000; | ||||
|     FLOAT_EXP  = 0x7F800000, | ||||
|     FLOAT_FRAC = 0x007FFFFF, | ||||
|     FLOAT_ZERO = 0x00000000; | ||||
| 
 | ||||
| union IntDouble { | ||||
| 	double d; | ||||
| 	u64 i; | ||||
|     double d; | ||||
|     u64 i; | ||||
| }; | ||||
| union IntFloat { | ||||
| 	float f; | ||||
| 	u32 i; | ||||
|     float f; | ||||
|     u32 i; | ||||
| }; | ||||
| 
 | ||||
| inline bool IsNAN(double d) | ||||
| { | ||||
| 	IntDouble x; x.d = d; | ||||
| 	return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | ||||
| 			 ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) ); | ||||
|     IntDouble x; x.d = d; | ||||
|     return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | ||||
|              ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) ); | ||||
| } | ||||
| 
 | ||||
| inline bool IsQNAN(double d) | ||||
| { | ||||
| 	IntDouble x; x.d = d; | ||||
| 	return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | ||||
| 		     ((x.i & 0x0007fffffffffffULL) == 0x000000000000000ULL) && | ||||
| 		     ((x.i & 0x000800000000000ULL) == 0x000800000000000ULL) ); | ||||
|     IntDouble x; x.d = d; | ||||
|     return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | ||||
|              ((x.i & 0x0007fffffffffffULL) == 0x000000000000000ULL) && | ||||
|              ((x.i & 0x000800000000000ULL) == 0x000800000000000ULL) ); | ||||
| } | ||||
| 
 | ||||
| inline bool IsSNAN(double d) | ||||
| { | ||||
| 	IntDouble x; x.d = d; | ||||
| 	return( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | ||||
| 			((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) && | ||||
| 			((x.i & 0x0008000000000000ULL) == DOUBLE_ZERO) ); | ||||
|     IntDouble x; x.d = d; | ||||
|     return( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | ||||
|             ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) && | ||||
|             ((x.i & 0x0008000000000000ULL) == DOUBLE_ZERO) ); | ||||
| } | ||||
| 
 | ||||
| inline float FlushToZero(float f) | ||||
| { | ||||
| 	IntFloat x; x.f = f; | ||||
| 	if ((x.i & FLOAT_EXP) == 0) | ||||
| 		x.i &= FLOAT_SIGN;  // turn into signed zero
 | ||||
| 	return x.f; | ||||
|     IntFloat x; x.f = f; | ||||
|     if ((x.i & FLOAT_EXP) == 0) | ||||
|         x.i &= FLOAT_SIGN;  // turn into signed zero
 | ||||
|     return x.f; | ||||
| } | ||||
| 
 | ||||
| inline double FlushToZeroAsFloat(double d) | ||||
| { | ||||
| 	IntDouble x; x.d = d; | ||||
| 	if ((x.i & DOUBLE_EXP) < 0x3800000000000000ULL) | ||||
| 		x.i &= DOUBLE_SIGN;  // turn into signed zero
 | ||||
| 	return x.d; | ||||
|     IntDouble x; x.d = d; | ||||
|     if ((x.i & DOUBLE_EXP) < 0x3800000000000000ULL) | ||||
|         x.i &= DOUBLE_SIGN;  // turn into signed zero
 | ||||
|     return x.d; | ||||
| } | ||||
| 
 | ||||
| enum PPCFpClass | ||||
| { | ||||
| 	PPC_FPCLASS_QNAN = 0x11, | ||||
| 	PPC_FPCLASS_NINF = 0x9, | ||||
| 	PPC_FPCLASS_NN   = 0x8, | ||||
| 	PPC_FPCLASS_ND   = 0x18, | ||||
| 	PPC_FPCLASS_NZ   = 0x12, | ||||
| 	PPC_FPCLASS_PZ   = 0x2, | ||||
| 	PPC_FPCLASS_PD   = 0x14, | ||||
| 	PPC_FPCLASS_PN   = 0x4, | ||||
| 	PPC_FPCLASS_PINF = 0x5, | ||||
|     PPC_FPCLASS_QNAN = 0x11, | ||||
|     PPC_FPCLASS_NINF = 0x9, | ||||
|     PPC_FPCLASS_NN   = 0x8, | ||||
|     PPC_FPCLASS_ND   = 0x18, | ||||
|     PPC_FPCLASS_NZ   = 0x12, | ||||
|     PPC_FPCLASS_PZ   = 0x2, | ||||
|     PPC_FPCLASS_PD   = 0x14, | ||||
|     PPC_FPCLASS_PN   = 0x4, | ||||
|     PPC_FPCLASS_PINF = 0x5, | ||||
| }; | ||||
| 
 | ||||
| // Uses PowerPC conventions for the return value, so it can be easily
 | ||||
|  | @ -93,42 +93,42 @@ u32 ClassifyFloat(float fvalue); | |||
| template<class T> | ||||
| struct Rectangle | ||||
| { | ||||
| 	T left; | ||||
| 	T top; | ||||
| 	T right; | ||||
| 	T bottom; | ||||
|     T left; | ||||
|     T top; | ||||
|     T right; | ||||
|     T bottom; | ||||
| 
 | ||||
| 	Rectangle() | ||||
| 	{ } | ||||
|     Rectangle() | ||||
|     { } | ||||
| 
 | ||||
| 	Rectangle(T theLeft, T theTop, T theRight, T theBottom) | ||||
| 		: left(theLeft), top(theTop), right(theRight), bottom(theBottom) | ||||
| 	{ } | ||||
| 	 | ||||
| 	bool operator==(const Rectangle& r) { return left==r.left && top==r.top && right==r.right && bottom==r.bottom; } | ||||
|     Rectangle(T theLeft, T theTop, T theRight, T theBottom) | ||||
|         : left(theLeft), top(theTop), right(theRight), bottom(theBottom) | ||||
|     { } | ||||
|      | ||||
|     bool operator==(const Rectangle& r) { return left==r.left && top==r.top && right==r.right && bottom==r.bottom; } | ||||
| 
 | ||||
| 	T GetWidth() const { return abs(right - left); } | ||||
| 	T GetHeight() const { return abs(bottom - top); } | ||||
|     T GetWidth() const { return abs(right - left); } | ||||
|     T GetHeight() const { return abs(bottom - top); } | ||||
| 
 | ||||
| 	// If the rectangle is in a coordinate system with a lower-left origin, use
 | ||||
| 	// this Clamp.
 | ||||
| 	void ClampLL(T x1, T y1, T x2, T y2) | ||||
| 	{ | ||||
| 		if (left < x1) left = x1; | ||||
| 		if (right > x2) right = x2; | ||||
| 		if (top > y1) top = y1; | ||||
| 		if (bottom < y2) bottom = y2; | ||||
| 	} | ||||
|     // If the rectangle is in a coordinate system with a lower-left origin, use
 | ||||
|     // this Clamp.
 | ||||
|     void ClampLL(T x1, T y1, T x2, T y2) | ||||
|     { | ||||
|         if (left < x1) left = x1; | ||||
|         if (right > x2) right = x2; | ||||
|         if (top > y1) top = y1; | ||||
|         if (bottom < y2) bottom = y2; | ||||
|     } | ||||
| 
 | ||||
| 	// If the rectangle is in a coordinate system with an upper-left origin,
 | ||||
| 	// use this Clamp.
 | ||||
| 	void ClampUL(T x1, T y1, T x2, T y2)  | ||||
| 	{ | ||||
| 		if (left < x1) left = x1; | ||||
| 		if (right > x2) right = x2; | ||||
| 		if (top < y1) top = y1; | ||||
| 		if (bottom > y2) bottom = y2; | ||||
| 	} | ||||
|     // If the rectangle is in a coordinate system with an upper-left origin,
 | ||||
|     // use this Clamp.
 | ||||
|     void ClampUL(T x1, T y1, T x2, T y2)  | ||||
|     { | ||||
|         if (left < x1) left = x1; | ||||
|         if (right > x2) right = x2; | ||||
|         if (top < y1) top = y1; | ||||
|         if (bottom > y2) bottom = y2; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| }  // namespace MathUtil
 | ||||
|  | @ -138,28 +138,28 @@ inline double pow2(double x) {return x * x;} | |||
| 
 | ||||
| float MathFloatVectorSum(const std::vector<float>&); | ||||
| 
 | ||||
| #define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1)) | ||||
| #define ROUND_DOWN(x, a)	((x) & ~((a) - 1)) | ||||
| #define ROUND_UP(x, a)        (((x) + (a) - 1) & ~((a) - 1)) | ||||
| #define ROUND_DOWN(x, a)    ((x) & ~((a) - 1)) | ||||
| 
 | ||||
| // Rounds down. 0 -> undefined
 | ||||
| inline u64 Log2(u64 val) | ||||
| { | ||||
| #if defined(__GNUC__) | ||||
| 	return 63 - __builtin_clzll(val); | ||||
|     return 63 - __builtin_clzll(val); | ||||
| 
 | ||||
| #elif defined(_MSC_VER) && defined(_M_X64) | ||||
| 	unsigned long result = -1; | ||||
| 	_BitScanReverse64(&result, val); | ||||
| 	return result; | ||||
|     unsigned long result = -1; | ||||
|     _BitScanReverse64(&result, val); | ||||
|     return result; | ||||
| 
 | ||||
| #else | ||||
| 	u64 result = -1; | ||||
| 	while (val != 0) | ||||
| 	{ | ||||
| 		val >>= 1; | ||||
| 		++result; | ||||
| 	} | ||||
| 	return result; | ||||
|     u64 result = -1; | ||||
|     while (val != 0) | ||||
|     { | ||||
|         val >>= 1; | ||||
|         ++result; | ||||
|     } | ||||
|     return result; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  | @ -169,32 +169,32 @@ inline u64 Log2(u64 val) | |||
| class Matrix33 | ||||
| { | ||||
| public: | ||||
| 	static void LoadIdentity(Matrix33 &mtx); | ||||
|     static void LoadIdentity(Matrix33 &mtx); | ||||
| 
 | ||||
| 	// set mtx to be a rotation matrix around the x axis
 | ||||
| 	static void RotateX(Matrix33 &mtx, float rad); | ||||
| 	// set mtx to be a rotation matrix around the y axis
 | ||||
| 	static void RotateY(Matrix33 &mtx, float rad); | ||||
|     // set mtx to be a rotation matrix around the x axis
 | ||||
|     static void RotateX(Matrix33 &mtx, float rad); | ||||
|     // set mtx to be a rotation matrix around the y axis
 | ||||
|     static void RotateY(Matrix33 &mtx, float rad); | ||||
| 
 | ||||
| 	// set result = a x b
 | ||||
| 	static void Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result); | ||||
| 	static void Multiply(const Matrix33 &a, const float vec[3], float result[3]); | ||||
|     // set result = a x b
 | ||||
|     static void Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result); | ||||
|     static void Multiply(const Matrix33 &a, const float vec[3], float result[3]); | ||||
| 
 | ||||
| 	float data[9]; | ||||
|     float data[9]; | ||||
| }; | ||||
| 
 | ||||
| class Matrix44 | ||||
| { | ||||
| public: | ||||
| 	static void LoadIdentity(Matrix44 &mtx); | ||||
| 	static void LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33); | ||||
| 	static void Set(Matrix44 &mtx, const float mtxArray[16]); | ||||
|     static void LoadIdentity(Matrix44 &mtx); | ||||
|     static void LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33); | ||||
|     static void Set(Matrix44 &mtx, const float mtxArray[16]); | ||||
| 
 | ||||
| 	static void Translate(Matrix44 &mtx, const float vec[3]); | ||||
|     static void Translate(Matrix44 &mtx, const float vec[3]); | ||||
| 
 | ||||
| 	static void Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result); | ||||
|     static void Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result); | ||||
| 
 | ||||
| 	float data[16]; | ||||
|     float data[16]; | ||||
| }; | ||||
| 
 | ||||
| #endif // _MATH_UTIL_H_
 | ||||
|  |  | |||
|  | @ -27,148 +27,148 @@ | |||
| void* AllocateExecutableMemory(size_t size, bool low) | ||||
| { | ||||
| #if defined(_WIN32) | ||||
| 	void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); | ||||
|     void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); | ||||
| #else | ||||
| 	static char *map_hint = 0; | ||||
|     static char *map_hint = 0; | ||||
| #if defined(__x86_64__) && !defined(MAP_32BIT) | ||||
| 	// This OS has no flag to enforce allocation below the 4 GB boundary,
 | ||||
| 	// but if we hint that we want a low address it is very likely we will
 | ||||
| 	// get one.
 | ||||
| 	// An older version of this code used MAP_FIXED, but that has the side
 | ||||
| 	// effect of discarding already mapped pages that happen to be in the
 | ||||
| 	// requested virtual memory range (such as the emulated RAM, sometimes).
 | ||||
| 	if (low && (!map_hint)) | ||||
| 		map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */ | ||||
|     // This OS has no flag to enforce allocation below the 4 GB boundary,
 | ||||
|     // but if we hint that we want a low address it is very likely we will
 | ||||
|     // get one.
 | ||||
|     // An older version of this code used MAP_FIXED, but that has the side
 | ||||
|     // effect of discarding already mapped pages that happen to be in the
 | ||||
|     // requested virtual memory range (such as the emulated RAM, sometimes).
 | ||||
|     if (low && (!map_hint)) | ||||
|         map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */ | ||||
| #endif | ||||
| 	void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, | ||||
| 		MAP_ANON | MAP_PRIVATE | ||||
|     void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, | ||||
|         MAP_ANON | MAP_PRIVATE | ||||
| #if defined(__x86_64__) && defined(MAP_32BIT) | ||||
| 		| (low ? MAP_32BIT : 0) | ||||
|         | (low ? MAP_32BIT : 0) | ||||
| #endif | ||||
| 		, -1, 0); | ||||
|         , -1, 0); | ||||
| #endif /* defined(_WIN32) */ | ||||
| 
 | ||||
| 	// printf("Mapped executable memory at %p (size %ld)\n", ptr,
 | ||||
| 	//	(unsigned long)size);
 | ||||
| 	 | ||||
|     // printf("Mapped executable memory at %p (size %ld)\n", ptr,
 | ||||
|     //    (unsigned long)size);
 | ||||
|      | ||||
| #if defined(__FreeBSD__) | ||||
| 	if (ptr == MAP_FAILED) | ||||
| 	{ | ||||
| 		ptr = NULL; | ||||
|     if (ptr == MAP_FAILED) | ||||
|     { | ||||
|         ptr = NULL; | ||||
| #else | ||||
| 	if (ptr == NULL) | ||||
| 	{ | ||||
| #endif	 | ||||
| 		PanicAlert("Failed to allocate executable memory"); | ||||
| 	} | ||||
|     if (ptr == NULL) | ||||
|     { | ||||
| #endif     | ||||
|         PanicAlert("Failed to allocate executable memory"); | ||||
|     } | ||||
| #if !defined(_WIN32) && defined(__x86_64__) && !defined(MAP_32BIT) | ||||
| 	else | ||||
| 	{ | ||||
| 		if (low) | ||||
| 		{ | ||||
| 			map_hint += size; | ||||
| 			map_hint = (char*)round_page(map_hint); /* round up to the next page */ | ||||
| 			// printf("Next map will (hopefully) be at %p\n", map_hint);
 | ||||
| 		} | ||||
| 	} | ||||
|     else | ||||
|     { | ||||
|         if (low) | ||||
|         { | ||||
|             map_hint += size; | ||||
|             map_hint = (char*)round_page(map_hint); /* round up to the next page */ | ||||
|             // printf("Next map will (hopefully) be at %p\n", map_hint);
 | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
| #if defined(_M_X64) | ||||
| 	if ((u64)ptr >= 0x80000000 && low == true) | ||||
| 		PanicAlert("Executable memory ended up above 2GB!"); | ||||
|     if ((u64)ptr >= 0x80000000 && low == true) | ||||
|         PanicAlert("Executable memory ended up above 2GB!"); | ||||
| #endif | ||||
| 
 | ||||
| 	return ptr; | ||||
|     return ptr; | ||||
| } | ||||
| 
 | ||||
| void* AllocateMemoryPages(size_t size) | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); | ||||
|     void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); | ||||
| #else | ||||
| 	void* ptr = mmap(0, size, PROT_READ | PROT_WRITE, | ||||
| 			MAP_ANON | MAP_PRIVATE, -1, 0); | ||||
|     void* ptr = mmap(0, size, PROT_READ | PROT_WRITE, | ||||
|             MAP_ANON | MAP_PRIVATE, -1, 0); | ||||
| #endif | ||||
| 
 | ||||
| 	// printf("Mapped memory at %p (size %ld)\n", ptr,
 | ||||
| 	//	(unsigned long)size);
 | ||||
|     // printf("Mapped memory at %p (size %ld)\n", ptr,
 | ||||
|     //    (unsigned long)size);
 | ||||
| 
 | ||||
| 	if (ptr == NULL) | ||||
| 		PanicAlert("Failed to allocate raw memory"); | ||||
|     if (ptr == NULL) | ||||
|         PanicAlert("Failed to allocate raw memory"); | ||||
| 
 | ||||
| 	return ptr; | ||||
|     return ptr; | ||||
| } | ||||
| 
 | ||||
| void* AllocateAlignedMemory(size_t size,size_t alignment) | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	void* ptr =  _aligned_malloc(size,alignment); | ||||
|     void* ptr =  _aligned_malloc(size,alignment); | ||||
| #else | ||||
| 	void* ptr = NULL; | ||||
|     void* ptr = NULL; | ||||
| #ifdef ANDROID | ||||
| 	ptr = memalign(alignment, size); | ||||
|     ptr = memalign(alignment, size); | ||||
| #else | ||||
| 	if (posix_memalign(&ptr, alignment, size) != 0) | ||||
| 		ERROR_LOG(MEMMAP, "Failed to allocate aligned memory"); | ||||
|     if (posix_memalign(&ptr, alignment, size) != 0) | ||||
|         ERROR_LOG(MEMMAP, "Failed to allocate aligned memory"); | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| 	// printf("Mapped memory at %p (size %ld)\n", ptr,
 | ||||
| 	//	(unsigned long)size);
 | ||||
|     // printf("Mapped memory at %p (size %ld)\n", ptr,
 | ||||
|     //    (unsigned long)size);
 | ||||
| 
 | ||||
| 	if (ptr == NULL) | ||||
| 		PanicAlert("Failed to allocate aligned memory"); | ||||
|     if (ptr == NULL) | ||||
|         PanicAlert("Failed to allocate aligned memory"); | ||||
| 
 | ||||
| 	return ptr; | ||||
|     return ptr; | ||||
| } | ||||
| 
 | ||||
| void FreeMemoryPages(void* ptr, size_t size) | ||||
| { | ||||
| 	if (ptr) | ||||
| 	{ | ||||
|     if (ptr) | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 	 | ||||
| 		if (!VirtualFree(ptr, 0, MEM_RELEASE)) | ||||
| 			PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg()); | ||||
| 		ptr = NULL; // Is this our responsibility?
 | ||||
| 	 | ||||
|      | ||||
|         if (!VirtualFree(ptr, 0, MEM_RELEASE)) | ||||
|             PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg()); | ||||
|         ptr = NULL; // Is this our responsibility?
 | ||||
|      | ||||
| #else | ||||
| 		munmap(ptr, size); | ||||
|         munmap(ptr, size); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FreeAlignedMemory(void* ptr) | ||||
| { | ||||
| 	if (ptr) | ||||
| 	{ | ||||
|     if (ptr) | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 	_aligned_free(ptr); | ||||
|     _aligned_free(ptr); | ||||
| #else | ||||
| 	free(ptr); | ||||
|     free(ptr); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	DWORD oldValue; | ||||
| 	if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue)) | ||||
| 		PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg()); | ||||
|     DWORD oldValue; | ||||
|     if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue)) | ||||
|         PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg()); | ||||
| #else | ||||
| 	mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ); | ||||
|     mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	DWORD oldValue; | ||||
| 	if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue)) | ||||
| 		PanicAlert("UnWriteProtectMemory failed!\n%s", GetLastErrorMsg()); | ||||
|     DWORD oldValue; | ||||
|     if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue)) | ||||
|         PanicAlert("UnWriteProtectMemory failed!\n%s", GetLastErrorMsg()); | ||||
| #else | ||||
| 	mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ); | ||||
|     mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  | @ -176,22 +176,22 @@ std::string MemUsage() | |||
| { | ||||
| #ifdef _WIN32 | ||||
| #pragma comment(lib, "psapi") | ||||
| 	DWORD processID = GetCurrentProcessId(); | ||||
| 	HANDLE hProcess; | ||||
| 	PROCESS_MEMORY_COUNTERS pmc; | ||||
| 	std::string Ret; | ||||
|     DWORD processID = GetCurrentProcessId(); | ||||
|     HANDLE hProcess; | ||||
|     PROCESS_MEMORY_COUNTERS pmc; | ||||
|     std::string Ret; | ||||
| 
 | ||||
| 	// Print information about the memory usage of the process.
 | ||||
|     // Print information about the memory usage of the process.
 | ||||
| 
 | ||||
| 	hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); | ||||
| 	if (NULL == hProcess) return "MemUsage Error"; | ||||
|     hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); | ||||
|     if (NULL == hProcess) return "MemUsage Error"; | ||||
| 
 | ||||
| 	if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) | ||||
| 		Ret = StringFromFormat("%s K", ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); | ||||
|     if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) | ||||
|         Ret = StringFromFormat("%s K", ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); | ||||
| 
 | ||||
| 	CloseHandle(hProcess); | ||||
| 	return Ret; | ||||
|     CloseHandle(hProcess); | ||||
|     return Ret; | ||||
| #else | ||||
| 	return ""; | ||||
|     return ""; | ||||
| #endif | ||||
| } | ||||
|  |  | |||
|  | @ -18,20 +18,20 @@ | |||
| // This function might change the error code.
 | ||||
| const char* GetLastErrorMsg() | ||||
| { | ||||
| 	static const size_t buff_size = 255; | ||||
|     static const size_t buff_size = 255; | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| 	static __declspec(thread) char err_str[buff_size] = {}; | ||||
|     static __declspec(thread) char err_str[buff_size] = {}; | ||||
| 
 | ||||
| 	FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), | ||||
| 		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||||
| 		err_str, buff_size, NULL); | ||||
|     FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), | ||||
|         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||||
|         err_str, buff_size, NULL); | ||||
| #else | ||||
| 	static __thread char err_str[buff_size] = {}; | ||||
|     static __thread char err_str[buff_size] = {}; | ||||
| 
 | ||||
| 	// Thread safe (XSI-compliant)
 | ||||
| 	strerror_r(errno, err_str, buff_size); | ||||
|     // Thread safe (XSI-compliant)
 | ||||
|     strerror_r(errno, err_str, buff_size); | ||||
| #endif | ||||
| 
 | ||||
| 	return err_str; | ||||
|     return err_str; | ||||
| } | ||||
|  |  | |||
|  | @ -18,90 +18,90 @@ static StringTranslator str_translator = DefaultStringTranslator; | |||
| // wxWidgets is enabled we will use wxMsgAlert() that is defined in Main.cpp
 | ||||
| void RegisterMsgAlertHandler(MsgAlertHandler handler) | ||||
| { | ||||
| 	msg_handler = handler; | ||||
|     msg_handler = handler; | ||||
| } | ||||
| 
 | ||||
| // Select translation function.  For wxWidgets use wxStringTranslator in Main.cpp
 | ||||
| void RegisterStringTranslator(StringTranslator translator) | ||||
| { | ||||
| 	str_translator = translator; | ||||
|     str_translator = translator; | ||||
| } | ||||
| 
 | ||||
| // enable/disable the alert handler
 | ||||
| void SetEnableAlert(bool enable) | ||||
| { | ||||
| 	AlertEnabled = enable; | ||||
|     AlertEnabled = enable; | ||||
| } | ||||
| 
 | ||||
| // This is the first stop for gui alerts where the log is updated and the
 | ||||
| // correct window is shown
 | ||||
| bool MsgAlert(bool yes_no, int Style, const char* format, ...) | ||||
| { | ||||
| 	// Read message and write it to the log
 | ||||
| 	std::string caption; | ||||
| 	char buffer[2048]; | ||||
|     // Read message and write it to the log
 | ||||
|     std::string caption; | ||||
|     char buffer[2048]; | ||||
| 
 | ||||
| 	static std::string info_caption; | ||||
| 	static std::string warn_caption; | ||||
| 	static std::string ques_caption; | ||||
| 	static std::string crit_caption; | ||||
|     static std::string info_caption; | ||||
|     static std::string warn_caption; | ||||
|     static std::string ques_caption; | ||||
|     static std::string crit_caption; | ||||
| 
 | ||||
| 	if (!info_caption.length()) | ||||
| 	{ | ||||
| 		info_caption = str_translator(_trans("Information")); | ||||
| 		ques_caption = str_translator(_trans("Question")); | ||||
| 		warn_caption = str_translator(_trans("Warning")); | ||||
| 		crit_caption = str_translator(_trans("Critical")); | ||||
| 	} | ||||
|     if (!info_caption.length()) | ||||
|     { | ||||
|         info_caption = str_translator(_trans("Information")); | ||||
|         ques_caption = str_translator(_trans("Question")); | ||||
|         warn_caption = str_translator(_trans("Warning")); | ||||
|         crit_caption = str_translator(_trans("Critical")); | ||||
|     } | ||||
| 
 | ||||
| 	switch(Style) | ||||
| 	{ | ||||
| 		case INFORMATION: | ||||
| 			caption = info_caption; | ||||
| 			break; | ||||
| 		case QUESTION: | ||||
| 			caption = ques_caption; | ||||
| 			break; | ||||
| 		case WARNING: | ||||
| 			caption = warn_caption; | ||||
| 			break; | ||||
| 		case CRITICAL: | ||||
| 			caption = crit_caption; | ||||
| 			break; | ||||
| 	} | ||||
|     switch(Style) | ||||
|     { | ||||
|         case INFORMATION: | ||||
|             caption = info_caption; | ||||
|             break; | ||||
|         case QUESTION: | ||||
|             caption = ques_caption; | ||||
|             break; | ||||
|         case WARNING: | ||||
|             caption = warn_caption; | ||||
|             break; | ||||
|         case CRITICAL: | ||||
|             caption = crit_caption; | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
| 	va_list args; | ||||
| 	va_start(args, format); | ||||
| 	CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args); | ||||
| 	va_end(args); | ||||
|     va_list args; | ||||
|     va_start(args, format); | ||||
|     CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args); | ||||
|     va_end(args); | ||||
| 
 | ||||
| 	ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer); | ||||
|     ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer); | ||||
| 
 | ||||
| 	// Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored
 | ||||
| 	if (msg_handler && (AlertEnabled || Style == QUESTION || Style == CRITICAL)) | ||||
| 		return msg_handler(caption.c_str(), buffer, yes_no, Style); | ||||
|     // Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored
 | ||||
|     if (msg_handler && (AlertEnabled || Style == QUESTION || Style == CRITICAL)) | ||||
|         return msg_handler(caption.c_str(), buffer, yes_no, Style); | ||||
| 
 | ||||
| 	return true; | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| // Default non library dependent panic alert
 | ||||
| bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style) | ||||
| { | ||||
| //#ifdef _WIN32
 | ||||
| //	int STYLE = MB_ICONINFORMATION;
 | ||||
| //	if (Style == QUESTION) STYLE = MB_ICONQUESTION;
 | ||||
| //	if (Style == WARNING) STYLE = MB_ICONWARNING;
 | ||||
| //    int STYLE = MB_ICONINFORMATION;
 | ||||
| //    if (Style == QUESTION) STYLE = MB_ICONQUESTION;
 | ||||
| //    if (Style == WARNING) STYLE = MB_ICONWARNING;
 | ||||
| //
 | ||||
| //	return IDYES == MessageBox(0, UTF8ToTStr(text).c_str(), UTF8ToTStr(caption).c_str(), STYLE | (yes_no ? MB_YESNO : MB_OK));
 | ||||
| //    return IDYES == MessageBox(0, UTF8ToTStr(text).c_str(), UTF8ToTStr(caption).c_str(), STYLE | (yes_no ? MB_YESNO : MB_OK));
 | ||||
| //#else
 | ||||
| 	printf("%s\n", text); | ||||
| 	return true; | ||||
|     printf("%s\n", text); | ||||
|     return true; | ||||
| //#endif
 | ||||
| } | ||||
| 
 | ||||
| // Default (non) translator
 | ||||
| std::string DefaultStringTranslator(const char* text) | ||||
| { | ||||
| 	return text; | ||||
|     return text; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,10 +10,10 @@ | |||
| // Message alerts
 | ||||
| enum MSG_TYPE | ||||
| { | ||||
| 	INFORMATION, | ||||
| 	QUESTION, | ||||
| 	WARNING, | ||||
| 	CRITICAL | ||||
|     INFORMATION, | ||||
|     QUESTION, | ||||
|     WARNING, | ||||
|     CRITICAL | ||||
| }; | ||||
| 
 | ||||
| typedef bool (*MsgAlertHandler)(const char* caption, const char* text,  | ||||
|  | @ -25,49 +25,49 @@ void RegisterStringTranslator(StringTranslator translator); | |||
| 
 | ||||
| extern bool MsgAlert(bool yes_no, int Style, const char* format, ...) | ||||
| #ifdef __GNUC__ | ||||
| 	__attribute__((format(printf, 3, 4))) | ||||
|     __attribute__((format(printf, 3, 4))) | ||||
| #endif | ||||
| 	; | ||||
|     ; | ||||
| void SetEnableAlert(bool enable); | ||||
| 
 | ||||
| #ifndef GEKKO | ||||
| #ifdef _WIN32 | ||||
| 	#define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__)  | ||||
| 	#define PanicAlert(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__)  | ||||
| 	#define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__)  | ||||
| 	#define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__)  | ||||
| 	#define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__)  | ||||
| 	// Use these macros (that do the same thing) if the message should be translated.
 | ||||
| 	#define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__)  | ||||
| 	#define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__)  | ||||
| 	#define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__)  | ||||
| 	#define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__)  | ||||
| 	#define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__)  | ||||
|     #define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__)  | ||||
|     #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__)  | ||||
|     #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__)  | ||||
|     #define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__)  | ||||
|     #define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__)  | ||||
|     // Use these macros (that do the same thing) if the message should be translated.
 | ||||
|     #define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__)  | ||||
|     #define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__)  | ||||
|     #define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__)  | ||||
|     #define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__)  | ||||
|     #define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__)  | ||||
| #else | ||||
| 	#define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__)  | ||||
| 	#define PanicAlert(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__)  | ||||
| 	#define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__)  | ||||
| 	#define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__)  | ||||
| 	#define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__)  | ||||
| 	// Use these macros (that do the same thing) if the message should be translated.
 | ||||
| 	#define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__)  | ||||
| 	#define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__)  | ||||
| 	#define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__)  | ||||
| 	#define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__)  | ||||
| 	#define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__)  | ||||
|     #define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__)  | ||||
|     #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__)  | ||||
|     #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__)  | ||||
|     #define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__)  | ||||
|     #define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__)  | ||||
|     // Use these macros (that do the same thing) if the message should be translated.
 | ||||
|     #define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__)  | ||||
|     #define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__)  | ||||
|     #define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__)  | ||||
|     #define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__)  | ||||
|     #define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__)  | ||||
| #endif | ||||
| #else | ||||
| // GEKKO
 | ||||
| 	#define SuccessAlert(format, ...) ; | ||||
| 	#define PanicAlert(format, ...) ; | ||||
| 	#define PanicYesNo(format, ...) ; | ||||
| 	#define AskYesNo(format, ...) ; | ||||
| 	#define CriticalAlert(format, ...) ; | ||||
| 	#define SuccessAlertT(format, ...) ; | ||||
| 	#define PanicAlertT(format, ...) ; | ||||
| 	#define PanicYesNoT(format, ...) ; | ||||
| 	#define AskYesNoT(format, ...) ; | ||||
| 	#define CriticalAlertT(format, ...) ; | ||||
|     #define SuccessAlert(format, ...) ; | ||||
|     #define PanicAlert(format, ...) ; | ||||
|     #define PanicYesNo(format, ...) ; | ||||
|     #define AskYesNo(format, ...) ; | ||||
|     #define CriticalAlert(format, ...) ; | ||||
|     #define SuccessAlertT(format, ...) ; | ||||
|     #define PanicAlertT(format, ...) ; | ||||
|     #define PanicYesNoT(format, ...) ; | ||||
|     #define AskYesNoT(format, ...) ; | ||||
|     #define CriticalAlertT(format, ...) ; | ||||
| #endif | ||||
| 
 | ||||
| #endif // _MSGHANDLER_H_
 | ||||
|  |  | |||
|  | @ -76,9 +76,9 @@ | |||
| #define EMU_FASTCALL __fastcall | ||||
| 
 | ||||
| inline struct tm* localtime_r(const time_t *clock, struct tm *result) { | ||||
| 	if (localtime_s(result, clock) == 0) | ||||
| 		return result; | ||||
| 	return NULL; | ||||
|     if (localtime_s(result, clock) == 0) | ||||
|         return result; | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| #else | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| #ifndef CONDITION_VARIABLE_H_ | ||||
| #define CONDITION_VARIABLE_H_ | ||||
| 
 | ||||
| #define GCC_VER(x,y,z)	((x) * 10000 + (y) * 100 + (z)) | ||||
| #define GCC_VER(x,y,z)    ((x) * 10000 + (y) * 100 + (z)) | ||||
| #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) | ||||
| 
 | ||||
| #ifndef __has_include | ||||
|  | @ -47,121 +47,121 @@ namespace std | |||
| class condition_variable | ||||
| { | ||||
| #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | ||||
| 	typedef CONDITION_VARIABLE native_type; | ||||
|     typedef CONDITION_VARIABLE native_type; | ||||
| #elif defined(_WIN32) | ||||
| 	typedef HANDLE native_type; | ||||
|     typedef HANDLE native_type; | ||||
| #else | ||||
| 	typedef pthread_cond_t native_type; | ||||
|     typedef pthread_cond_t native_type; | ||||
| #endif | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
| #ifdef USE_EVENTS | ||||
| 	typedef native_type native_handle_type; | ||||
|     typedef native_type native_handle_type; | ||||
| #else | ||||
| 	typedef native_type* native_handle_type; | ||||
|     typedef native_type* native_handle_type; | ||||
| #endif | ||||
| 
 | ||||
| 	condition_variable() | ||||
| 	{ | ||||
|     condition_variable() | ||||
|     { | ||||
| #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | ||||
| 		InitializeConditionVariable(&m_handle); | ||||
|         InitializeConditionVariable(&m_handle); | ||||
| #elif defined(_WIN32) | ||||
| 		m_handle = CreateEvent(NULL, false, false, NULL); | ||||
|         m_handle = CreateEvent(NULL, false, false, NULL); | ||||
| #else | ||||
| 		pthread_cond_init(&m_handle, NULL); | ||||
|         pthread_cond_init(&m_handle, NULL); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	~condition_variable() | ||||
| 	{ | ||||
|     ~condition_variable() | ||||
|     { | ||||
| #if defined(_WIN32) && !defined(USE_CONDITION_VARIABLES) | ||||
| 		CloseHandle(m_handle); | ||||
|         CloseHandle(m_handle); | ||||
| #elif !defined(_WIN32) | ||||
| 		pthread_cond_destroy(&m_handle); | ||||
|         pthread_cond_destroy(&m_handle); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	condition_variable(const condition_variable&) /*= delete*/; | ||||
| 	condition_variable& operator=(const condition_variable&) /*= delete*/; | ||||
|     condition_variable(const condition_variable&) /*= delete*/; | ||||
|     condition_variable& operator=(const condition_variable&) /*= delete*/; | ||||
| 
 | ||||
| 	void notify_one() | ||||
| 	{ | ||||
|     void notify_one() | ||||
|     { | ||||
| #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | ||||
| 		WakeConditionVariable(&m_handle); | ||||
|         WakeConditionVariable(&m_handle); | ||||
| #elif defined(_WIN32) | ||||
| 		SetEvent(m_handle); | ||||
|         SetEvent(m_handle); | ||||
| #else | ||||
| 		pthread_cond_signal(&m_handle); | ||||
|         pthread_cond_signal(&m_handle); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	void notify_all() | ||||
| 	{ | ||||
|     void notify_all() | ||||
|     { | ||||
| #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | ||||
| 		WakeAllConditionVariable(&m_handle); | ||||
|         WakeAllConditionVariable(&m_handle); | ||||
| #elif defined(_WIN32) | ||||
| 		// TODO: broken
 | ||||
| 		SetEvent(m_handle); | ||||
|         // TODO: broken
 | ||||
|         SetEvent(m_handle); | ||||
| #else | ||||
| 		pthread_cond_broadcast(&m_handle); | ||||
|         pthread_cond_broadcast(&m_handle); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	void wait(unique_lock<mutex>& lock) | ||||
| 	{ | ||||
|     void wait(unique_lock<mutex>& lock) | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 	#ifdef USE_SRWLOCKS | ||||
| 		SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0); | ||||
| 	#elif defined(USE_CONDITION_VARIABLES) | ||||
| 		SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE); | ||||
| 	#else | ||||
| 		// TODO: broken, the unlock and wait need to be atomic
 | ||||
| 		lock.unlock(); | ||||
| 		WaitForSingleObject(m_handle, INFINITE); | ||||
| 		lock.lock(); | ||||
| 	#endif | ||||
|     #ifdef USE_SRWLOCKS | ||||
|         SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0); | ||||
|     #elif defined(USE_CONDITION_VARIABLES) | ||||
|         SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE); | ||||
|     #else | ||||
|         // TODO: broken, the unlock and wait need to be atomic
 | ||||
|         lock.unlock(); | ||||
|         WaitForSingleObject(m_handle, INFINITE); | ||||
|         lock.lock(); | ||||
|     #endif | ||||
| #else | ||||
| 		pthread_cond_wait(&m_handle, lock.mutex()->native_handle()); | ||||
|         pthread_cond_wait(&m_handle, lock.mutex()->native_handle()); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	template <class Predicate> | ||||
| 	void wait(unique_lock<mutex>& lock, Predicate pred) | ||||
| 	{ | ||||
| 		while (!pred()) | ||||
| 			wait(lock); | ||||
| 	} | ||||
|     template <class Predicate> | ||||
|     void wait(unique_lock<mutex>& lock, Predicate pred) | ||||
|     { | ||||
|         while (!pred()) | ||||
|             wait(lock); | ||||
|     } | ||||
| 
 | ||||
| 	//template <class Clock, class Duration>
 | ||||
| 	//cv_status wait_until(unique_lock<mutex>& lock,
 | ||||
| 	//	const chrono::time_point<Clock, Duration>& abs_time);
 | ||||
|     //template <class Clock, class Duration>
 | ||||
|     //cv_status wait_until(unique_lock<mutex>& lock,
 | ||||
|     //    const chrono::time_point<Clock, Duration>& abs_time);
 | ||||
| 
 | ||||
| 	//template <class Clock, class Duration, class Predicate>
 | ||||
| 	//	bool wait_until(unique_lock<mutex>& lock,
 | ||||
| 	//	const chrono::time_point<Clock, Duration>& abs_time,
 | ||||
| 	//	Predicate pred);
 | ||||
|     //template <class Clock, class Duration, class Predicate>
 | ||||
|     //    bool wait_until(unique_lock<mutex>& lock,
 | ||||
|     //    const chrono::time_point<Clock, Duration>& abs_time,
 | ||||
|     //    Predicate pred);
 | ||||
| 
 | ||||
| 	//template <class Rep, class Period>
 | ||||
| 	//cv_status wait_for(unique_lock<mutex>& lock,
 | ||||
| 	//	const chrono::duration<Rep, Period>& rel_time);
 | ||||
|     //template <class Rep, class Period>
 | ||||
|     //cv_status wait_for(unique_lock<mutex>& lock,
 | ||||
|     //    const chrono::duration<Rep, Period>& rel_time);
 | ||||
| 
 | ||||
| 	//template <class Rep, class Period, class Predicate>
 | ||||
| 	//	bool wait_for(unique_lock<mutex>& lock,
 | ||||
| 	//	const chrono::duration<Rep, Period>& rel_time,
 | ||||
| 	//	Predicate pred);
 | ||||
|     //template <class Rep, class Period, class Predicate>
 | ||||
|     //    bool wait_for(unique_lock<mutex>& lock,
 | ||||
|     //    const chrono::duration<Rep, Period>& rel_time,
 | ||||
|     //    Predicate pred);
 | ||||
| 
 | ||||
| 	native_handle_type native_handle() | ||||
| 	{ | ||||
|     native_handle_type native_handle() | ||||
|     { | ||||
| #ifdef USE_EVENTS | ||||
| 		return m_handle; | ||||
|         return m_handle; | ||||
| #else | ||||
| 		return &m_handle; | ||||
|         return &m_handle; | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| 	native_type m_handle; | ||||
|     native_type m_handle; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| #ifndef MUTEX_H_ | ||||
| #define MUTEX_H_ | ||||
| 
 | ||||
| #define GCC_VER(x,y,z)	((x) * 10000 + (y) * 100 + (z)) | ||||
| #define GCC_VER(x,y,z)    ((x) * 10000 + (y) * 100 + (z)) | ||||
| #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) | ||||
| 
 | ||||
| #ifndef __has_include | ||||
|  | @ -46,72 +46,72 @@ namespace std | |||
| class recursive_mutex | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	typedef CRITICAL_SECTION native_type; | ||||
|     typedef CRITICAL_SECTION native_type; | ||||
| #else | ||||
| 	typedef pthread_mutex_t native_type; | ||||
|     typedef pthread_mutex_t native_type; | ||||
| #endif | ||||
| 
 | ||||
| public: | ||||
| 	typedef native_type* native_handle_type; | ||||
|     typedef native_type* native_handle_type; | ||||
| 
 | ||||
| 	recursive_mutex(const recursive_mutex&) /*= delete*/; | ||||
| 	recursive_mutex& operator=(const recursive_mutex&) /*= delete*/; | ||||
|     recursive_mutex(const recursive_mutex&) /*= delete*/; | ||||
|     recursive_mutex& operator=(const recursive_mutex&) /*= delete*/; | ||||
| 
 | ||||
| 	recursive_mutex() | ||||
| 	{ | ||||
|     recursive_mutex() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		InitializeCriticalSection(&m_handle); | ||||
|         InitializeCriticalSection(&m_handle); | ||||
| #else | ||||
| 		pthread_mutexattr_t attr; | ||||
| 		pthread_mutexattr_init(&attr); | ||||
| 		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | ||||
| 		pthread_mutex_init(&m_handle, &attr); | ||||
|         pthread_mutexattr_t attr; | ||||
|         pthread_mutexattr_init(&attr); | ||||
|         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | ||||
|         pthread_mutex_init(&m_handle, &attr); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	~recursive_mutex() | ||||
| 	{ | ||||
|     ~recursive_mutex() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		DeleteCriticalSection(&m_handle); | ||||
|         DeleteCriticalSection(&m_handle); | ||||
| #else | ||||
| 		pthread_mutex_destroy(&m_handle); | ||||
|         pthread_mutex_destroy(&m_handle); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	void lock() | ||||
| 	{ | ||||
|     void lock() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		EnterCriticalSection(&m_handle); | ||||
|         EnterCriticalSection(&m_handle); | ||||
| #else | ||||
| 		pthread_mutex_lock(&m_handle); | ||||
|         pthread_mutex_lock(&m_handle); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	void unlock() | ||||
| 	{ | ||||
|     void unlock() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		LeaveCriticalSection(&m_handle); | ||||
|         LeaveCriticalSection(&m_handle); | ||||
| #else | ||||
| 		pthread_mutex_unlock(&m_handle); | ||||
|         pthread_mutex_unlock(&m_handle); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	bool try_lock() | ||||
| 	{ | ||||
|     bool try_lock() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		return (0 != TryEnterCriticalSection(&m_handle)); | ||||
|         return (0 != TryEnterCriticalSection(&m_handle)); | ||||
| #else | ||||
| 		return !pthread_mutex_trylock(&m_handle); | ||||
| #endif	 | ||||
| 	} | ||||
|         return !pthread_mutex_trylock(&m_handle); | ||||
| #endif     | ||||
|     } | ||||
| 
 | ||||
| 	native_handle_type native_handle() | ||||
| 	{ | ||||
| 		return &m_handle; | ||||
| 	} | ||||
|     native_handle_type native_handle() | ||||
|     { | ||||
|         return &m_handle; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| 	native_type m_handle; | ||||
|     native_type m_handle; | ||||
| }; | ||||
| 
 | ||||
| #if !defined(_WIN32) || defined(USE_SRWLOCKS) | ||||
|  | @ -119,74 +119,74 @@ private: | |||
| class mutex | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	typedef SRWLOCK native_type; | ||||
|     typedef SRWLOCK native_type; | ||||
| #else | ||||
| 	typedef pthread_mutex_t native_type; | ||||
|     typedef pthread_mutex_t native_type; | ||||
| #endif | ||||
| 
 | ||||
| public: | ||||
| 	typedef native_type* native_handle_type; | ||||
|     typedef native_type* native_handle_type; | ||||
| 
 | ||||
| 	mutex(const mutex&) /*= delete*/; | ||||
| 	mutex& operator=(const mutex&) /*= delete*/; | ||||
|     mutex(const mutex&) /*= delete*/; | ||||
|     mutex& operator=(const mutex&) /*= delete*/; | ||||
| 
 | ||||
| 	mutex() | ||||
| 	{ | ||||
|     mutex() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		InitializeSRWLock(&m_handle); | ||||
|         InitializeSRWLock(&m_handle); | ||||
| #else | ||||
| 		pthread_mutex_init(&m_handle, NULL); | ||||
|         pthread_mutex_init(&m_handle, NULL); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	~mutex() | ||||
| 	{ | ||||
|     ~mutex() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| #else | ||||
| 		pthread_mutex_destroy(&m_handle); | ||||
|         pthread_mutex_destroy(&m_handle); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	void lock() | ||||
| 	{ | ||||
|     void lock() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		AcquireSRWLockExclusive(&m_handle); | ||||
|         AcquireSRWLockExclusive(&m_handle); | ||||
| #else | ||||
| 		pthread_mutex_lock(&m_handle); | ||||
|         pthread_mutex_lock(&m_handle); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	void unlock() | ||||
| 	{ | ||||
|     void unlock() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		ReleaseSRWLockExclusive(&m_handle); | ||||
|         ReleaseSRWLockExclusive(&m_handle); | ||||
| #else | ||||
| 		pthread_mutex_unlock(&m_handle); | ||||
|         pthread_mutex_unlock(&m_handle); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	bool try_lock() | ||||
| 	{ | ||||
|     bool try_lock() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		// XXX TryAcquireSRWLockExclusive requires Windows 7!
 | ||||
| 		// return (0 != TryAcquireSRWLockExclusive(&m_handle));
 | ||||
| 		return false; | ||||
|         // XXX TryAcquireSRWLockExclusive requires Windows 7!
 | ||||
|         // return (0 != TryAcquireSRWLockExclusive(&m_handle));
 | ||||
|         return false; | ||||
| #else | ||||
| 		return !pthread_mutex_trylock(&m_handle); | ||||
|         return !pthread_mutex_trylock(&m_handle); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	native_handle_type native_handle() | ||||
| 	{ | ||||
| 		return &m_handle; | ||||
| 	} | ||||
|     native_handle_type native_handle() | ||||
|     { | ||||
|         return &m_handle; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| 	native_type m_handle; | ||||
|     native_type m_handle; | ||||
| }; | ||||
| 
 | ||||
| #else | ||||
| typedef recursive_mutex mutex;	// just use CriticalSections
 | ||||
| typedef recursive_mutex mutex;    // just use CriticalSections
 | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
|  | @ -198,165 +198,165 @@ template <class Mutex> | |||
| class lock_guard | ||||
| { | ||||
| public: | ||||
| 	typedef Mutex mutex_type; | ||||
|     typedef Mutex mutex_type; | ||||
| 
 | ||||
| 	explicit lock_guard(mutex_type& m) | ||||
| 		: pm(m) | ||||
| 	{ | ||||
| 		m.lock(); | ||||
| 	} | ||||
|     explicit lock_guard(mutex_type& m) | ||||
|         : pm(m) | ||||
|     { | ||||
|         m.lock(); | ||||
|     } | ||||
| 
 | ||||
| 	lock_guard(mutex_type& m, adopt_lock_t) | ||||
| 		: pm(m) | ||||
| 	{ | ||||
| 	} | ||||
|     lock_guard(mutex_type& m, adopt_lock_t) | ||||
|         : pm(m) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
| 	~lock_guard() | ||||
| 	{ | ||||
| 		pm.unlock(); | ||||
| 	} | ||||
|     ~lock_guard() | ||||
|     { | ||||
|         pm.unlock(); | ||||
|     } | ||||
| 
 | ||||
| 	lock_guard(lock_guard const&) /*= delete*/; | ||||
| 	lock_guard& operator=(lock_guard const&) /*= delete*/; | ||||
|     lock_guard(lock_guard const&) /*= delete*/; | ||||
|     lock_guard& operator=(lock_guard const&) /*= delete*/; | ||||
| 
 | ||||
| private: | ||||
| 	mutex_type& pm; | ||||
|     mutex_type& pm; | ||||
| }; | ||||
| 
 | ||||
| template <class Mutex> | ||||
| class unique_lock | ||||
| { | ||||
| public: | ||||
| 	typedef Mutex mutex_type; | ||||
|     typedef Mutex mutex_type; | ||||
| 
 | ||||
| 	unique_lock() | ||||
| 		: pm(NULL), owns(false) | ||||
| 	{} | ||||
|     unique_lock() | ||||
|         : pm(NULL), owns(false) | ||||
|     {} | ||||
| 
 | ||||
| 	/*explicit*/ unique_lock(mutex_type& m) | ||||
| 		: pm(&m), owns(true) | ||||
| 	{ | ||||
| 		m.lock(); | ||||
| 	} | ||||
|     /*explicit*/ unique_lock(mutex_type& m) | ||||
|         : pm(&m), owns(true) | ||||
|     { | ||||
|         m.lock(); | ||||
|     } | ||||
| 
 | ||||
| 	unique_lock(mutex_type& m, defer_lock_t) | ||||
| 		: pm(&m), owns(false) | ||||
| 	{} | ||||
|     unique_lock(mutex_type& m, defer_lock_t) | ||||
|         : pm(&m), owns(false) | ||||
|     {} | ||||
| 
 | ||||
| 	unique_lock(mutex_type& m, try_to_lock_t) | ||||
| 		: pm(&m), owns(m.try_lock()) | ||||
| 	{} | ||||
|     unique_lock(mutex_type& m, try_to_lock_t) | ||||
|         : pm(&m), owns(m.try_lock()) | ||||
|     {} | ||||
| 
 | ||||
| 	unique_lock(mutex_type& m, adopt_lock_t) | ||||
| 		: pm(&m), owns(true) | ||||
| 	{} | ||||
|     unique_lock(mutex_type& m, adopt_lock_t) | ||||
|         : pm(&m), owns(true) | ||||
|     {} | ||||
| 
 | ||||
| 	//template <class Clock, class Duration>
 | ||||
| 	//unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
 | ||||
|     //template <class Clock, class Duration>
 | ||||
|     //unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
 | ||||
| 
 | ||||
| 	//template <class Rep, class Period>
 | ||||
| 	//unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
 | ||||
|     //template <class Rep, class Period>
 | ||||
|     //unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
 | ||||
| 
 | ||||
| 	~unique_lock() | ||||
| 	{ | ||||
| 		if (owns_lock()) | ||||
| 			mutex()->unlock(); | ||||
| 	} | ||||
|     ~unique_lock() | ||||
|     { | ||||
|         if (owns_lock()) | ||||
|             mutex()->unlock(); | ||||
|     } | ||||
| 
 | ||||
| #ifdef USE_RVALUE_REFERENCES | ||||
| 	unique_lock& operator=(const unique_lock&) /*= delete*/; | ||||
|     unique_lock& operator=(const unique_lock&) /*= delete*/; | ||||
| 
 | ||||
| 	unique_lock& operator=(unique_lock&& other) | ||||
| 	{ | ||||
|     unique_lock& operator=(unique_lock&& other) | ||||
|     { | ||||
| #else | ||||
| 	unique_lock& operator=(const unique_lock& u) | ||||
| 	{ | ||||
| 		// ugly const_cast to get around lack of rvalue references
 | ||||
| 		unique_lock& other = const_cast<unique_lock&>(u); | ||||
|     unique_lock& operator=(const unique_lock& u) | ||||
|     { | ||||
|         // ugly const_cast to get around lack of rvalue references
 | ||||
|         unique_lock& other = const_cast<unique_lock&>(u); | ||||
| #endif | ||||
| 		swap(other); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	 | ||||
|         swap(other); | ||||
|         return *this; | ||||
|     } | ||||
|      | ||||
| #ifdef USE_RVALUE_REFERENCES | ||||
| 	unique_lock(const unique_lock&) /*= delete*/; | ||||
| 	 | ||||
| 	unique_lock(unique_lock&& other) | ||||
| 		: pm(NULL), owns(false) | ||||
| 	{ | ||||
|     unique_lock(const unique_lock&) /*= delete*/; | ||||
|      | ||||
|     unique_lock(unique_lock&& other) | ||||
|         : pm(NULL), owns(false) | ||||
|     { | ||||
| #else | ||||
| 	unique_lock(const unique_lock& u) | ||||
| 		: pm(NULL), owns(false) | ||||
| 	{ | ||||
| 		// ugly const_cast to get around lack of rvalue references
 | ||||
| 		unique_lock& other = const_cast<unique_lock&>(u);	 | ||||
|     unique_lock(const unique_lock& u) | ||||
|         : pm(NULL), owns(false) | ||||
|     { | ||||
|         // ugly const_cast to get around lack of rvalue references
 | ||||
|         unique_lock& other = const_cast<unique_lock&>(u);     | ||||
| #endif | ||||
| 		swap(other); | ||||
| 	} | ||||
|         swap(other); | ||||
|     } | ||||
| 
 | ||||
| 	void lock() | ||||
| 	{ | ||||
| 		mutex()->lock(); | ||||
| 		owns = true; | ||||
| 	} | ||||
|     void lock() | ||||
|     { | ||||
|         mutex()->lock(); | ||||
|         owns = true; | ||||
|     } | ||||
| 
 | ||||
| 	bool try_lock() | ||||
| 	{ | ||||
| 		owns = mutex()->try_lock(); | ||||
| 		return owns; | ||||
| 	} | ||||
|     bool try_lock() | ||||
|     { | ||||
|         owns = mutex()->try_lock(); | ||||
|         return owns; | ||||
|     } | ||||
| 
 | ||||
| 	//template <class Rep, class Period>
 | ||||
| 	//bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
 | ||||
| 	//template <class Clock, class Duration>
 | ||||
| 	//bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
 | ||||
| 	 | ||||
| 	void unlock() | ||||
| 	{ | ||||
| 		mutex()->unlock(); | ||||
| 		owns = false; | ||||
| 	} | ||||
|     //template <class Rep, class Period>
 | ||||
|     //bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
 | ||||
|     //template <class Clock, class Duration>
 | ||||
|     //bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
 | ||||
|      | ||||
|     void unlock() | ||||
|     { | ||||
|         mutex()->unlock(); | ||||
|         owns = false; | ||||
|     } | ||||
| 
 | ||||
| 	void swap(unique_lock& u) | ||||
| 	{ | ||||
| 		std::swap(pm, u.pm); | ||||
| 		std::swap(owns, u.owns); | ||||
| 	} | ||||
|     void swap(unique_lock& u) | ||||
|     { | ||||
|         std::swap(pm, u.pm); | ||||
|         std::swap(owns, u.owns); | ||||
|     } | ||||
| 
 | ||||
| 	mutex_type* release() | ||||
| 	{ | ||||
| 		auto const ret = mutex(); | ||||
|     mutex_type* release() | ||||
|     { | ||||
|         auto const ret = mutex(); | ||||
| 
 | ||||
| 		pm = NULL; | ||||
| 		owns = false; | ||||
|         pm = NULL; | ||||
|         owns = false; | ||||
| 
 | ||||
| 		return ret; | ||||
| 	} | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
| 	bool owns_lock() const | ||||
| 	{ | ||||
| 		return owns; | ||||
| 	} | ||||
|     bool owns_lock() const | ||||
|     { | ||||
|         return owns; | ||||
|     } | ||||
| 
 | ||||
| 	//explicit operator bool () const
 | ||||
| 	//{
 | ||||
| 	//	return owns_lock();
 | ||||
| 	//}
 | ||||
|     //explicit operator bool () const
 | ||||
|     //{
 | ||||
|     //    return owns_lock();
 | ||||
|     //}
 | ||||
| 
 | ||||
| 	mutex_type* mutex() const | ||||
| 	{ | ||||
| 		return pm; | ||||
| 	} | ||||
|     mutex_type* mutex() const | ||||
|     { | ||||
|         return pm; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| 	mutex_type* pm; | ||||
| 	bool owns; | ||||
|     mutex_type* pm; | ||||
|     bool owns; | ||||
| }; | ||||
| 
 | ||||
| template <class Mutex> | ||||
| void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) | ||||
| { | ||||
| 	x.swap(y); | ||||
|     x.swap(y); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| #ifndef STD_THREAD_H_ | ||||
| #define STD_THREAD_H_ | ||||
| 
 | ||||
| #define GCC_VER(x,y,z)	((x) * 10000 + (y) * 100 + (z)) | ||||
| #define GCC_VER(x,y,z)    ((x) * 10000 + (y) * 100 + (z)) | ||||
| #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) | ||||
| 
 | ||||
| #ifndef __has_include | ||||
|  | @ -77,209 +77,209 @@ namespace std | |||
| class thread | ||||
| { | ||||
| public: | ||||
| 	typedef THREAD_HANDLE native_handle_type; | ||||
|     typedef THREAD_HANDLE native_handle_type; | ||||
| 
 | ||||
| 	class id | ||||
| 	{ | ||||
| 		friend class thread; | ||||
| 	public: | ||||
| 		id() : m_thread(0) {} | ||||
| 		id(THREAD_ID _id) : m_thread(_id) {} | ||||
|     class id | ||||
|     { | ||||
|         friend class thread; | ||||
|     public: | ||||
|         id() : m_thread(0) {} | ||||
|         id(THREAD_ID _id) : m_thread(_id) {} | ||||
| 
 | ||||
| 		bool operator==(const id& rhs) const | ||||
| 		{ | ||||
| 			return m_thread == rhs.m_thread; | ||||
| 		} | ||||
|         bool operator==(const id& rhs) const | ||||
|         { | ||||
|             return m_thread == rhs.m_thread; | ||||
|         } | ||||
| 
 | ||||
| 		bool operator!=(const id& rhs) const | ||||
| 		{ | ||||
| 			return !(*this == rhs); | ||||
| 		} | ||||
|         bool operator!=(const id& rhs) const | ||||
|         { | ||||
|             return !(*this == rhs); | ||||
|         } | ||||
| 
 | ||||
| 		bool operator<(const id& rhs) const | ||||
| 		{ | ||||
| 			return m_thread < rhs.m_thread; | ||||
| 		} | ||||
|         bool operator<(const id& rhs) const | ||||
|         { | ||||
|             return m_thread < rhs.m_thread; | ||||
|         } | ||||
| 
 | ||||
| 	private: | ||||
| 		THREAD_ID m_thread; | ||||
| 	}; | ||||
|     private: | ||||
|         THREAD_ID m_thread; | ||||
|     }; | ||||
| 
 | ||||
| 	// no variadic template support in msvc
 | ||||
| 	//template <typename C, typename... A>
 | ||||
| 	//thread(C&& func, A&&... args);
 | ||||
|     // no variadic template support in msvc
 | ||||
|     //template <typename C, typename... A>
 | ||||
|     //thread(C&& func, A&&... args);
 | ||||
| 
 | ||||
| 	template <typename C> | ||||
| 	thread(C func) | ||||
| 	{ | ||||
| 		StartThread(new Func<C>(func)); | ||||
| 	} | ||||
|     template <typename C> | ||||
|     thread(C func) | ||||
|     { | ||||
|         StartThread(new Func<C>(func)); | ||||
|     } | ||||
| 
 | ||||
| 	template <typename C, typename A> | ||||
| 	thread(C func, A arg) | ||||
| 	{ | ||||
| 		StartThread(new FuncArg<C, A>(func, arg)); | ||||
| 	} | ||||
|     template <typename C, typename A> | ||||
|     thread(C func, A arg) | ||||
|     { | ||||
|         StartThread(new FuncArg<C, A>(func, arg)); | ||||
|     } | ||||
| 
 | ||||
| 	thread() /*= default;*/ {} | ||||
|     thread() /*= default;*/ {} | ||||
| 
 | ||||
| #ifdef USE_RVALUE_REFERENCES | ||||
| 	thread(const thread&) /*= delete*/; | ||||
|     thread(const thread&) /*= delete*/; | ||||
| 
 | ||||
| 	thread(thread&& other) | ||||
| 	{ | ||||
|     thread(thread&& other) | ||||
|     { | ||||
| #else | ||||
| 	thread(const thread& t) | ||||
| 	{ | ||||
| 		// ugly const_cast to get around lack of rvalue references
 | ||||
| 		thread& other = const_cast<thread&>(t); | ||||
|     thread(const thread& t) | ||||
|     { | ||||
|         // ugly const_cast to get around lack of rvalue references
 | ||||
|         thread& other = const_cast<thread&>(t); | ||||
| #endif | ||||
| 		swap(other); | ||||
| 	} | ||||
|         swap(other); | ||||
|     } | ||||
| 
 | ||||
| #ifdef USE_RVALUE_REFERENCES | ||||
| 	thread& operator=(const thread&) /*= delete*/; | ||||
|     thread& operator=(const thread&) /*= delete*/; | ||||
| 
 | ||||
| 	thread& operator=(thread&& other) | ||||
| 	{ | ||||
|     thread& operator=(thread&& other) | ||||
|     { | ||||
| #else | ||||
| 	thread& operator=(const thread& t) | ||||
| 	{ | ||||
| 		// ugly const_cast to get around lack of rvalue references
 | ||||
| 		thread& other = const_cast<thread&>(t); | ||||
|     thread& operator=(const thread& t) | ||||
|     { | ||||
|         // ugly const_cast to get around lack of rvalue references
 | ||||
|         thread& other = const_cast<thread&>(t); | ||||
| #endif | ||||
| 		if (joinable()) | ||||
| 			detach(); | ||||
| 		swap(other); | ||||
| 		return *this; | ||||
| 	} | ||||
|         if (joinable()) | ||||
|             detach(); | ||||
|         swap(other); | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
| 	~thread() | ||||
| 	{ | ||||
| 		if (joinable()) | ||||
| 			detach(); | ||||
| 	} | ||||
|     ~thread() | ||||
|     { | ||||
|         if (joinable()) | ||||
|             detach(); | ||||
|     } | ||||
| 
 | ||||
| 	bool joinable() const | ||||
| 	{ | ||||
| 		return m_id != id(); | ||||
| 	} | ||||
|     bool joinable() const | ||||
|     { | ||||
|         return m_id != id(); | ||||
|     } | ||||
| 
 | ||||
| 	id get_id() const | ||||
| 	{ | ||||
| 		return m_id; | ||||
| 	} | ||||
|     id get_id() const | ||||
|     { | ||||
|         return m_id; | ||||
|     } | ||||
| 
 | ||||
| 	native_handle_type native_handle() | ||||
| 	{ | ||||
|     native_handle_type native_handle() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		return m_handle; | ||||
|         return m_handle; | ||||
| #else | ||||
| 		return m_id.m_thread; | ||||
|         return m_id.m_thread; | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	void join() | ||||
| 	{ | ||||
|     void join() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		WaitForSingleObject(m_handle, INFINITE); | ||||
| 		detach(); | ||||
|         WaitForSingleObject(m_handle, INFINITE); | ||||
|         detach(); | ||||
| #else | ||||
| 		pthread_join(m_id.m_thread, NULL); | ||||
| 		m_id = id(); | ||||
|         pthread_join(m_id.m_thread, NULL); | ||||
|         m_id = id(); | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	void detach() | ||||
| 	{ | ||||
|     void detach() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		CloseHandle(m_handle); | ||||
|         CloseHandle(m_handle); | ||||
| #else | ||||
| 		pthread_detach(m_id.m_thread); | ||||
|         pthread_detach(m_id.m_thread); | ||||
| #endif | ||||
| 		m_id = id(); | ||||
| 	} | ||||
|         m_id = id(); | ||||
|     } | ||||
| 
 | ||||
| 	void swap(thread& other) | ||||
| 	{ | ||||
| 		std::swap(m_id, other.m_id); | ||||
|     void swap(thread& other) | ||||
|     { | ||||
|         std::swap(m_id, other.m_id); | ||||
| #ifdef _WIN32 | ||||
| 		std::swap(m_handle, other.m_handle); | ||||
|         std::swap(m_handle, other.m_handle); | ||||
| #endif | ||||
| 	} | ||||
| 	 | ||||
| 	static unsigned hardware_concurrency() | ||||
| 	{ | ||||
|     } | ||||
|      | ||||
|     static unsigned hardware_concurrency() | ||||
|     { | ||||
| #ifdef _WIN32 | ||||
| 		SYSTEM_INFO sysinfo; | ||||
| 		GetSystemInfo(&sysinfo); | ||||
| 		return static_cast<unsigned>(sysinfo.dwNumberOfProcessors); | ||||
|         SYSTEM_INFO sysinfo; | ||||
|         GetSystemInfo(&sysinfo); | ||||
|         return static_cast<unsigned>(sysinfo.dwNumberOfProcessors); | ||||
| #else | ||||
| 		return 0; | ||||
|         return 0; | ||||
| #endif | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| 	id m_id; | ||||
| 	 | ||||
|     id m_id; | ||||
|      | ||||
| #ifdef _WIN32 | ||||
| 	native_handle_type m_handle; | ||||
|     native_handle_type m_handle; | ||||
| #endif | ||||
| 
 | ||||
| 	template <typename F> | ||||
| 	void StartThread(F* param) | ||||
| 	{ | ||||
|     template <typename F> | ||||
|     void StartThread(F* param) | ||||
|     { | ||||
| #ifdef USE_BEGINTHREADEX | ||||
| 		m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread); | ||||
|         m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread); | ||||
| #elif defined(_WIN32) | ||||
| 		m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread); | ||||
|         m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread); | ||||
| #else | ||||
| 		pthread_attr_t attr; | ||||
| 		pthread_attr_init(&attr); | ||||
| 		pthread_attr_setstacksize(&attr, 1024 * 1024); | ||||
| 		if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param)) | ||||
| 			m_id = id(); | ||||
|         pthread_attr_t attr; | ||||
|         pthread_attr_init(&attr); | ||||
|         pthread_attr_setstacksize(&attr, 1024 * 1024); | ||||
|         if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param)) | ||||
|             m_id = id(); | ||||
| #endif | ||||
| 	} | ||||
| 	 | ||||
| 	template <typename C> | ||||
| 	class Func | ||||
| 	{ | ||||
| 	public: | ||||
| 		Func(C _func) : func(_func) {} | ||||
|     } | ||||
|      | ||||
|     template <typename C> | ||||
|     class Func | ||||
|     { | ||||
|     public: | ||||
|         Func(C _func) : func(_func) {} | ||||
| 
 | ||||
| 		void Run() { func(); } | ||||
|         void Run() { func(); } | ||||
| 
 | ||||
| 	private: | ||||
| 		C const func; | ||||
| 	}; | ||||
|     private: | ||||
|         C const func; | ||||
|     }; | ||||
| 
 | ||||
| 	template <typename C, typename A> | ||||
| 	class FuncArg | ||||
| 	{ | ||||
| 	public: | ||||
| 		FuncArg(C _func, A _arg) : func(_func), arg(_arg) {} | ||||
|     template <typename C, typename A> | ||||
|     class FuncArg | ||||
|     { | ||||
|     public: | ||||
|         FuncArg(C _func, A _arg) : func(_func), arg(_arg) {} | ||||
| 
 | ||||
| 		void Run() { func(arg); } | ||||
|         void Run() { func(arg); } | ||||
| 
 | ||||
| 	private: | ||||
| 		C const func; | ||||
| 		A arg; | ||||
| 	}; | ||||
|     private: | ||||
|         C const func; | ||||
|         A arg; | ||||
|     }; | ||||
| 
 | ||||
| 	template <typename F> | ||||
| 	static THREAD_RETURN RunAndDelete(void* param) | ||||
| 	{ | ||||
|     template <typename F> | ||||
|     static THREAD_RETURN RunAndDelete(void* param) | ||||
|     { | ||||
| #ifdef __APPLE__ | ||||
| 		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
|         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| #endif | ||||
| 		static_cast<F*>(param)->Run(); | ||||
| 		delete static_cast<F*>(param); | ||||
|         static_cast<F*>(param)->Run(); | ||||
|         delete static_cast<F*>(param); | ||||
| #ifdef __APPLE__ | ||||
| 		[pool release]; | ||||
|         [pool release]; | ||||
| #endif | ||||
| 		return 0; | ||||
| 	} | ||||
|         return 0; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| namespace this_thread | ||||
|  | @ -288,24 +288,24 @@ namespace this_thread | |||
| inline void yield() | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	SwitchToThread(); | ||||
|     SwitchToThread(); | ||||
| #else | ||||
| 	sleep(0); | ||||
|     sleep(0); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| inline thread::id get_id() | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	return GetCurrentThreadId(); | ||||
|     return GetCurrentThreadId(); | ||||
| #else | ||||
| 	return pthread_self(); | ||||
|     return pthread_self(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| }	// namespace this_thread
 | ||||
| }    // namespace this_thread
 | ||||
| 
 | ||||
| }	// namespace std
 | ||||
| }    // namespace std
 | ||||
| 
 | ||||
| #undef USE_RVALUE_REFERENCES | ||||
| #undef USE_BEGINTHREADEX | ||||
|  |  | |||
|  | @ -11,131 +11,131 @@ | |||
| #include "string_util.h" | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| 	#include <Windows.h> | ||||
|     #include <Windows.h> | ||||
| #else | ||||
| 	#include <iconv.h> | ||||
| 	#include <errno.h> | ||||
|     #include <iconv.h> | ||||
|     #include <errno.h> | ||||
| #endif | ||||
| 
 | ||||
| // faster than sscanf
 | ||||
| bool AsciiToHex(const char* _szValue, u32& result) | ||||
| { | ||||
| 	char *endptr = NULL; | ||||
| 	const u32 value = strtoul(_szValue, &endptr, 16); | ||||
|     char *endptr = NULL; | ||||
|     const u32 value = strtoul(_szValue, &endptr, 16); | ||||
| 
 | ||||
| 	if (!endptr || *endptr) | ||||
| 		return false; | ||||
|     if (!endptr || *endptr) | ||||
|         return false; | ||||
| 
 | ||||
| 	result = value; | ||||
| 	return true; | ||||
|     result = value; | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) | ||||
| { | ||||
| 	int writtenCount; | ||||
|     int writtenCount; | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| 	// You would think *printf are simple, right? Iterate on each character,
 | ||||
| 	// if it's a format specifier handle it properly, etc.
 | ||||
| 	//
 | ||||
| 	// Nooooo. Not according to the C standard.
 | ||||
| 	//
 | ||||
| 	// According to the C99 standard (7.19.6.1 "The fprintf function")
 | ||||
| 	//     The format shall be a multibyte character sequence
 | ||||
| 	//
 | ||||
| 	// Because some character encodings might have '%' signs in the middle of
 | ||||
| 	// a multibyte sequence (SJIS for example only specifies that the first
 | ||||
| 	// byte of a 2 byte sequence is "high", the second byte can be anything),
 | ||||
| 	// printf functions have to decode the multibyte sequences and try their
 | ||||
| 	// best to not screw up.
 | ||||
| 	//
 | ||||
| 	// Unfortunately, on Windows, the locale for most languages is not UTF-8
 | ||||
| 	// as we would need. Notably, for zh_TW, Windows chooses EUC-CN as the
 | ||||
| 	// locale, and completely fails when trying to decode UTF-8 as EUC-CN.
 | ||||
| 	//
 | ||||
| 	// On the other hand, the fix is simple: because we use UTF-8, no such
 | ||||
| 	// multibyte handling is required as we can simply assume that no '%' char
 | ||||
| 	// will be present in the middle of a multibyte sequence.
 | ||||
| 	//
 | ||||
| 	// This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l.
 | ||||
| 	static locale_t c_locale = NULL; | ||||
| 	if (!c_locale) | ||||
| 		c_locale = _create_locale(LC_ALL, ".1252"); | ||||
| 	writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); | ||||
|     // You would think *printf are simple, right? Iterate on each character,
 | ||||
|     // if it's a format specifier handle it properly, etc.
 | ||||
|     //
 | ||||
|     // Nooooo. Not according to the C standard.
 | ||||
|     //
 | ||||
|     // According to the C99 standard (7.19.6.1 "The fprintf function")
 | ||||
|     //     The format shall be a multibyte character sequence
 | ||||
|     //
 | ||||
|     // Because some character encodings might have '%' signs in the middle of
 | ||||
|     // a multibyte sequence (SJIS for example only specifies that the first
 | ||||
|     // byte of a 2 byte sequence is "high", the second byte can be anything),
 | ||||
|     // printf functions have to decode the multibyte sequences and try their
 | ||||
|     // best to not screw up.
 | ||||
|     //
 | ||||
|     // Unfortunately, on Windows, the locale for most languages is not UTF-8
 | ||||
|     // as we would need. Notably, for zh_TW, Windows chooses EUC-CN as the
 | ||||
|     // locale, and completely fails when trying to decode UTF-8 as EUC-CN.
 | ||||
|     //
 | ||||
|     // On the other hand, the fix is simple: because we use UTF-8, no such
 | ||||
|     // multibyte handling is required as we can simply assume that no '%' char
 | ||||
|     // will be present in the middle of a multibyte sequence.
 | ||||
|     //
 | ||||
|     // This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l.
 | ||||
|     static locale_t c_locale = NULL; | ||||
|     if (!c_locale) | ||||
|         c_locale = _create_locale(LC_ALL, ".1252"); | ||||
|     writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); | ||||
| #else | ||||
| 	writtenCount = vsnprintf(out, outsize, format, args); | ||||
|     writtenCount = vsnprintf(out, outsize, format, args); | ||||
| #endif | ||||
| 
 | ||||
| 	if (writtenCount > 0 && writtenCount < outsize) | ||||
| 	{ | ||||
| 		out[writtenCount] = '\0'; | ||||
| 		return true; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		out[outsize - 1] = '\0'; | ||||
| 		return false; | ||||
| 	} | ||||
|     if (writtenCount > 0 && writtenCount < outsize) | ||||
|     { | ||||
|         out[writtenCount] = '\0'; | ||||
|         return true; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         out[outsize - 1] = '\0'; | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| std::string StringFromFormat(const char* format, ...) | ||||
| { | ||||
| 	va_list args; | ||||
| 	char *buf = NULL; | ||||
|     va_list args; | ||||
|     char *buf = NULL; | ||||
| #ifdef _WIN32 | ||||
| 	int required = 0; | ||||
|     int required = 0; | ||||
| 
 | ||||
| 	va_start(args, format); | ||||
| 	required = _vscprintf(format, args); | ||||
| 	buf = new char[required + 1]; | ||||
| 	CharArrayFromFormatV(buf, required + 1, format, args); | ||||
| 	va_end(args); | ||||
|     va_start(args, format); | ||||
|     required = _vscprintf(format, args); | ||||
|     buf = new char[required + 1]; | ||||
|     CharArrayFromFormatV(buf, required + 1, format, args); | ||||
|     va_end(args); | ||||
| 
 | ||||
| 	std::string temp = buf; | ||||
| 	delete[] buf; | ||||
|     std::string temp = buf; | ||||
|     delete[] buf; | ||||
| #else | ||||
| 	va_start(args, format); | ||||
| 	if (vasprintf(&buf, format, args) < 0) | ||||
| 		ERROR_LOG(COMMON, "Unable to allocate memory for string"); | ||||
| 	va_end(args); | ||||
|     va_start(args, format); | ||||
|     if (vasprintf(&buf, format, args) < 0) | ||||
|         ERROR_LOG(COMMON, "Unable to allocate memory for string"); | ||||
|     va_end(args); | ||||
| 
 | ||||
| 	std::string temp = buf; | ||||
| 	free(buf); | ||||
|     std::string temp = buf; | ||||
|     free(buf); | ||||
| #endif | ||||
| 	return temp; | ||||
|     return temp; | ||||
| } | ||||
| 
 | ||||
| // For Debugging. Read out an u8 array.
 | ||||
| std::string ArrayToString(const u8 *data, u32 size, int line_len, bool spaces) | ||||
| { | ||||
| 	std::ostringstream oss; | ||||
| 	oss << std::setfill('0') << std::hex; | ||||
| 	 | ||||
| 	for (int line = 0; size; ++data, --size) | ||||
| 	{ | ||||
| 		oss << std::setw(2) << (int)*data; | ||||
| 		 | ||||
| 		if (line_len == ++line) | ||||
| 		{ | ||||
| 			oss << '\n'; | ||||
| 			line = 0; | ||||
| 		} | ||||
| 		else if (spaces) | ||||
| 			oss << ' '; | ||||
| 	} | ||||
|     std::ostringstream oss; | ||||
|     oss << std::setfill('0') << std::hex; | ||||
|      | ||||
|     for (int line = 0; size; ++data, --size) | ||||
|     { | ||||
|         oss << std::setw(2) << (int)*data; | ||||
|          | ||||
|         if (line_len == ++line) | ||||
|         { | ||||
|             oss << '\n'; | ||||
|             line = 0; | ||||
|         } | ||||
|         else if (spaces) | ||||
|             oss << ' '; | ||||
|     } | ||||
| 
 | ||||
| 	return oss.str(); | ||||
|     return oss.str(); | ||||
| } | ||||
| 
 | ||||
| // Turns "  hej " into "hej". Also handles tabs.
 | ||||
| std::string StripSpaces(const std::string &str) | ||||
| { | ||||
| 	const size_t s = str.find_first_not_of(" \t\r\n"); | ||||
|     const size_t s = str.find_first_not_of(" \t\r\n"); | ||||
| 
 | ||||
| 	if (str.npos != s) | ||||
| 		return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); | ||||
| 	else | ||||
| 		return ""; | ||||
|     if (str.npos != s) | ||||
|         return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); | ||||
|     else | ||||
|         return ""; | ||||
| } | ||||
| 
 | ||||
| // "\"hello\"" is turned to "hello"
 | ||||
|  | @ -143,137 +143,137 @@ std::string StripSpaces(const std::string &str) | |||
| // ends, as done by StripSpaces above, for example.
 | ||||
| std::string StripQuotes(const std::string& s) | ||||
| { | ||||
| 	if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) | ||||
| 		return s.substr(1, s.size() - 2); | ||||
| 	else | ||||
| 		return s; | ||||
|     if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) | ||||
|         return s.substr(1, s.size() - 2); | ||||
|     else | ||||
|         return s; | ||||
| } | ||||
| 
 | ||||
| bool TryParse(const std::string &str, u32 *const output) | ||||
| { | ||||
| 	char *endptr = NULL; | ||||
|     char *endptr = NULL; | ||||
| 
 | ||||
| 	// Reset errno to a value other than ERANGE
 | ||||
| 	errno = 0; | ||||
|     // Reset errno to a value other than ERANGE
 | ||||
|     errno = 0; | ||||
| 
 | ||||
| 	unsigned long value = strtoul(str.c_str(), &endptr, 0); | ||||
| 	 | ||||
| 	if (!endptr || *endptr) | ||||
| 		return false; | ||||
|     unsigned long value = strtoul(str.c_str(), &endptr, 0); | ||||
|      | ||||
|     if (!endptr || *endptr) | ||||
|         return false; | ||||
| 
 | ||||
| 	if (errno == ERANGE) | ||||
| 		return false; | ||||
|     if (errno == ERANGE) | ||||
|         return false; | ||||
| 
 | ||||
| #if ULONG_MAX > UINT_MAX | ||||
| 	if (value >= 0x100000000ull | ||||
| 	    && value <= 0xFFFFFFFF00000000ull) | ||||
| 		return false; | ||||
|     if (value >= 0x100000000ull | ||||
|         && value <= 0xFFFFFFFF00000000ull) | ||||
|         return false; | ||||
| #endif | ||||
| 
 | ||||
| 	*output = static_cast<u32>(value); | ||||
| 	return true; | ||||
|     *output = static_cast<u32>(value); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| bool TryParse(const std::string &str, bool *const output) | ||||
| { | ||||
| 	if ("1" == str || !strcasecmp("true", str.c_str())) | ||||
| 		*output = true; | ||||
| 	else if ("0" == str || !strcasecmp("false", str.c_str())) | ||||
| 		*output = false; | ||||
| 	else | ||||
| 		return false; | ||||
|     if ("1" == str || !strcasecmp("true", str.c_str())) | ||||
|         *output = true; | ||||
|     else if ("0" == str || !strcasecmp("false", str.c_str())) | ||||
|         *output = false; | ||||
|     else | ||||
|         return false; | ||||
| 
 | ||||
| 	return true; | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| std::string StringFromInt(int value) | ||||
| { | ||||
| 	char temp[16]; | ||||
| 	sprintf(temp, "%i", value); | ||||
| 	return temp; | ||||
|     char temp[16]; | ||||
|     sprintf(temp, "%i", value); | ||||
|     return temp; | ||||
| } | ||||
| 
 | ||||
| std::string StringFromBool(bool value) | ||||
| { | ||||
| 	return value ? "True" : "False"; | ||||
|     return value ? "True" : "False"; | ||||
| } | ||||
| 
 | ||||
| bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension) | ||||
| { | ||||
| 	if (full_path.empty()) | ||||
| 		return false; | ||||
|     if (full_path.empty()) | ||||
|         return false; | ||||
| 
 | ||||
| 	size_t dir_end = full_path.find_last_of("/" | ||||
| 	// windows needs the : included for something like just "C:" to be considered a directory
 | ||||
|     size_t dir_end = full_path.find_last_of("/" | ||||
|     // windows needs the : included for something like just "C:" to be considered a directory
 | ||||
| #ifdef _WIN32 | ||||
| 		":" | ||||
|         ":" | ||||
| #endif | ||||
| 	); | ||||
| 	if (std::string::npos == dir_end) | ||||
| 		dir_end = 0; | ||||
| 	else | ||||
| 		dir_end += 1; | ||||
|     ); | ||||
|     if (std::string::npos == dir_end) | ||||
|         dir_end = 0; | ||||
|     else | ||||
|         dir_end += 1; | ||||
| 
 | ||||
| 	size_t fname_end = full_path.rfind('.'); | ||||
| 	if (fname_end < dir_end || std::string::npos == fname_end) | ||||
| 		fname_end = full_path.size(); | ||||
|     size_t fname_end = full_path.rfind('.'); | ||||
|     if (fname_end < dir_end || std::string::npos == fname_end) | ||||
|         fname_end = full_path.size(); | ||||
| 
 | ||||
| 	if (_pPath) | ||||
| 		*_pPath = full_path.substr(0, dir_end); | ||||
|     if (_pPath) | ||||
|         *_pPath = full_path.substr(0, dir_end); | ||||
| 
 | ||||
| 	if (_pFilename) | ||||
| 		*_pFilename = full_path.substr(dir_end, fname_end - dir_end); | ||||
|     if (_pFilename) | ||||
|         *_pFilename = full_path.substr(dir_end, fname_end - dir_end); | ||||
| 
 | ||||
| 	if (_pExtension) | ||||
| 		*_pExtension = full_path.substr(fname_end); | ||||
|     if (_pExtension) | ||||
|         *_pExtension = full_path.substr(fname_end); | ||||
| 
 | ||||
| 	return true; | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, const std::string& _Filename) | ||||
| { | ||||
| 	_CompleteFilename = _Path; | ||||
|     _CompleteFilename = _Path; | ||||
| 
 | ||||
| 	// check for seperator
 | ||||
| 	if (DIR_SEP_CHR != *_CompleteFilename.rbegin()) | ||||
| 		_CompleteFilename += DIR_SEP_CHR; | ||||
|     // check for seperator
 | ||||
|     if (DIR_SEP_CHR != *_CompleteFilename.rbegin()) | ||||
|         _CompleteFilename += DIR_SEP_CHR; | ||||
| 
 | ||||
| 	// add the filename
 | ||||
| 	_CompleteFilename += _Filename; | ||||
|     // add the filename
 | ||||
|     _CompleteFilename += _Filename; | ||||
| } | ||||
| 
 | ||||
| void SplitString(const std::string& str, const char delim, std::vector<std::string>& output) | ||||
| { | ||||
| 	std::istringstream iss(str); | ||||
| 	output.resize(1); | ||||
|     std::istringstream iss(str); | ||||
|     output.resize(1); | ||||
| 
 | ||||
| 	while (std::getline(iss, *output.rbegin(), delim)) | ||||
| 		output.push_back(""); | ||||
|     while (std::getline(iss, *output.rbegin(), delim)) | ||||
|         output.push_back(""); | ||||
| 
 | ||||
| 	output.pop_back(); | ||||
|     output.pop_back(); | ||||
| } | ||||
| 
 | ||||
| std::string TabsToSpaces(int tab_size, const std::string &in) | ||||
| { | ||||
| 	const std::string spaces(tab_size, ' '); | ||||
| 	std::string out(in); | ||||
|     const std::string spaces(tab_size, ' '); | ||||
|     std::string out(in); | ||||
| 
 | ||||
| 	size_t i = 0; | ||||
| 	while (out.npos != (i = out.find('\t'))) | ||||
| 		out.replace(i, 1, spaces); | ||||
|     size_t i = 0; | ||||
|     while (out.npos != (i = out.find('\t'))) | ||||
|         out.replace(i, 1, spaces); | ||||
| 
 | ||||
| 	return out; | ||||
|     return out; | ||||
| } | ||||
| 
 | ||||
| std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) | ||||
| { | ||||
| 	while(1) | ||||
| 	{ | ||||
| 		size_t pos = result.find(src); | ||||
| 		if (pos == std::string::npos) break; | ||||
| 		result.replace(pos, src.size(), dest); | ||||
| 	} | ||||
| 	return result; | ||||
|     while(1) | ||||
|     { | ||||
|         size_t pos = result.find(src); | ||||
|         if (pos == std::string::npos) break; | ||||
|         result.replace(pos, src.size(), dest); | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| // UriDecode and UriEncode are from http://www.codeguru.com/cpp/cpp/string/conversions/print.php/c12759
 | ||||
|  | @ -287,161 +287,161 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st | |||
| 
 | ||||
| const char HEX2DEC[256] =  | ||||
| { | ||||
| 	/*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */ | ||||
| 	/* 0 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* 1 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* 2 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* 3 */  0, 1, 2, 3,  4, 5, 6, 7,  8, 9,16,16, 16,16,16,16, | ||||
|     /*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */ | ||||
|     /* 0 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* 1 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* 2 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* 3 */  0, 1, 2, 3,  4, 5, 6, 7,  8, 9,16,16, 16,16,16,16, | ||||
| 
 | ||||
| 	/* 4 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* 5 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* 6 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* 7 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* 4 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* 5 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* 6 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* 7 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 
 | ||||
| 	/* 8 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* 9 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* A */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* B */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* 8 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* 9 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* A */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* B */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 
 | ||||
| 	/* C */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* D */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* E */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
| 	/* F */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16 | ||||
|     /* C */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* D */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* E */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | ||||
|     /* F */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16 | ||||
| }; | ||||
| 
 | ||||
| std::string UriDecode(const std::string & sSrc) | ||||
| { | ||||
| 	// Note from RFC1630:  "Sequences which start with a percent sign
 | ||||
| 	// but are not followed by two hexadecimal characters (0-9, A-F) are reserved
 | ||||
| 	// for future extension"
 | ||||
|     // Note from RFC1630:  "Sequences which start with a percent sign
 | ||||
|     // but are not followed by two hexadecimal characters (0-9, A-F) are reserved
 | ||||
|     // for future extension"
 | ||||
| 
 | ||||
| 	const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); | ||||
| 	const size_t SRC_LEN = sSrc.length(); | ||||
| 	const unsigned char * const SRC_END = pSrc + SRC_LEN; | ||||
| 	const unsigned char * const SRC_LAST_DEC = SRC_END - 2;   // last decodable '%' 
 | ||||
|     const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); | ||||
|     const size_t SRC_LEN = sSrc.length(); | ||||
|     const unsigned char * const SRC_END = pSrc + SRC_LEN; | ||||
|     const unsigned char * const SRC_LAST_DEC = SRC_END - 2;   // last decodable '%' 
 | ||||
| 
 | ||||
| 	char * const pStart = new char[SRC_LEN]; | ||||
| 	char * pEnd = pStart; | ||||
|     char * const pStart = new char[SRC_LEN]; | ||||
|     char * pEnd = pStart; | ||||
| 
 | ||||
| 	while (pSrc < SRC_LAST_DEC) | ||||
| 	{ | ||||
| 		if (*pSrc == '%') | ||||
| 		{ | ||||
| 			char dec1, dec2; | ||||
| 			if (16 != (dec1 = HEX2DEC[*(pSrc + 1)]) | ||||
| 				&& 16 != (dec2 = HEX2DEC[*(pSrc + 2)])) | ||||
| 			{ | ||||
| 				*pEnd++ = (dec1 << 4) + dec2; | ||||
| 				pSrc += 3; | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
|     while (pSrc < SRC_LAST_DEC) | ||||
|     { | ||||
|         if (*pSrc == '%') | ||||
|         { | ||||
|             char dec1, dec2; | ||||
|             if (16 != (dec1 = HEX2DEC[*(pSrc + 1)]) | ||||
|                 && 16 != (dec2 = HEX2DEC[*(pSrc + 2)])) | ||||
|             { | ||||
|                 *pEnd++ = (dec1 << 4) + dec2; | ||||
|                 pSrc += 3; | ||||
|                 continue; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 		*pEnd++ = *pSrc++; | ||||
| 	} | ||||
|         *pEnd++ = *pSrc++; | ||||
|     } | ||||
| 
 | ||||
| 	// the last 2- chars
 | ||||
| 	while (pSrc < SRC_END) | ||||
| 		*pEnd++ = *pSrc++; | ||||
|     // the last 2- chars
 | ||||
|     while (pSrc < SRC_END) | ||||
|         *pEnd++ = *pSrc++; | ||||
| 
 | ||||
| 	std::string sResult(pStart, pEnd); | ||||
| 	delete [] pStart; | ||||
| 	return sResult; | ||||
|     std::string sResult(pStart, pEnd); | ||||
|     delete [] pStart; | ||||
|     return sResult; | ||||
| } | ||||
| 
 | ||||
| // Only alphanum is safe.
 | ||||
| const char SAFE[256] = | ||||
| { | ||||
| 	/*      0 1 2 3  4 5 6 7  8 9 A B  C D E F */ | ||||
| 	/* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
| 	/* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
| 	/* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
| 	/* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, | ||||
|     /*      0 1 2 3  4 5 6 7  8 9 A B  C D E F */ | ||||
|     /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
|     /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
|     /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
|     /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, | ||||
| 
 | ||||
| 	/* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, | ||||
| 	/* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, | ||||
| 	/* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, | ||||
| 	/* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, | ||||
|     /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, | ||||
|     /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, | ||||
|     /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, | ||||
|     /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, | ||||
| 
 | ||||
| 	/* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
| 	/* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
| 	/* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
| 	/* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
|     /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
|     /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
|     /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
|     /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
| 
 | ||||
| 	/* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
| 	/* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
| 	/* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
| 	/* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 | ||||
|     /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
|     /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
|     /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | ||||
|     /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 | ||||
| }; | ||||
| 
 | ||||
| std::string UriEncode(const std::string & sSrc) | ||||
| { | ||||
| 	const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; | ||||
| 	const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); | ||||
| 	const size_t SRC_LEN = sSrc.length(); | ||||
| 	unsigned char * const pStart = new unsigned char[SRC_LEN * 3]; | ||||
| 	unsigned char * pEnd = pStart; | ||||
| 	const unsigned char * const SRC_END = pSrc + SRC_LEN; | ||||
|     const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; | ||||
|     const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); | ||||
|     const size_t SRC_LEN = sSrc.length(); | ||||
|     unsigned char * const pStart = new unsigned char[SRC_LEN * 3]; | ||||
|     unsigned char * pEnd = pStart; | ||||
|     const unsigned char * const SRC_END = pSrc + SRC_LEN; | ||||
| 
 | ||||
| 	for (; pSrc < SRC_END; ++pSrc) | ||||
| 	{ | ||||
| 		if (SAFE[*pSrc])  | ||||
| 			*pEnd++ = *pSrc; | ||||
| 		else | ||||
| 		{ | ||||
| 			// escape this char
 | ||||
| 			*pEnd++ = '%'; | ||||
| 			*pEnd++ = DEC2HEX[*pSrc >> 4]; | ||||
| 			*pEnd++ = DEC2HEX[*pSrc & 0x0F]; | ||||
| 		} | ||||
| 	} | ||||
|     for (; pSrc < SRC_END; ++pSrc) | ||||
|     { | ||||
|         if (SAFE[*pSrc])  | ||||
|             *pEnd++ = *pSrc; | ||||
|         else | ||||
|         { | ||||
|             // escape this char
 | ||||
|             *pEnd++ = '%'; | ||||
|             *pEnd++ = DEC2HEX[*pSrc >> 4]; | ||||
|             *pEnd++ = DEC2HEX[*pSrc & 0x0F]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	std::string sResult((char *)pStart, (char *)pEnd); | ||||
| 	delete [] pStart; | ||||
| 	return sResult; | ||||
|     std::string sResult((char *)pStart, (char *)pEnd); | ||||
|     delete [] pStart; | ||||
|     return sResult; | ||||
| } | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| 
 | ||||
| std::string UTF16ToUTF8(const std::wstring& input) | ||||
| { | ||||
| 	auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), nullptr, 0, nullptr, nullptr); | ||||
|     auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), nullptr, 0, nullptr, nullptr); | ||||
| 
 | ||||
| 	std::string output; | ||||
| 	output.resize(size); | ||||
|     std::string output; | ||||
|     output.resize(size); | ||||
| 
 | ||||
| 	if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr)) | ||||
| 		output.clear(); | ||||
|     if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr)) | ||||
|         output.clear(); | ||||
| 
 | ||||
| 	return output; | ||||
|     return output; | ||||
| } | ||||
| 
 | ||||
| std::wstring CPToUTF16(u32 code_page, const std::string& input) | ||||
| { | ||||
| 	auto const size = MultiByteToWideChar(code_page, 0, input.data(), input.size(), nullptr, 0); | ||||
|     auto const size = MultiByteToWideChar(code_page, 0, input.data(), input.size(), nullptr, 0); | ||||
| 
 | ||||
| 	std::wstring output; | ||||
| 	output.resize(size); | ||||
|     std::wstring output; | ||||
|     output.resize(size); | ||||
| 
 | ||||
| 	if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size())) | ||||
| 		output.clear(); | ||||
|     if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size())) | ||||
|         output.clear(); | ||||
| 
 | ||||
| 	return output; | ||||
|     return output; | ||||
| } | ||||
| 
 | ||||
| std::wstring UTF8ToUTF16(const std::string& input) | ||||
| { | ||||
| 	return CPToUTF16(CP_UTF8, input); | ||||
|     return CPToUTF16(CP_UTF8, input); | ||||
| } | ||||
| 
 | ||||
| std::string SHIFTJISToUTF8(const std::string& input) | ||||
| { | ||||
| 	return UTF16ToUTF8(CPToUTF16(932, input)); | ||||
|     return UTF16ToUTF8(CPToUTF16(932, input)); | ||||
| } | ||||
| 
 | ||||
| std::string CP1252ToUTF8(const std::string& input) | ||||
| { | ||||
| 	return UTF16ToUTF8(CPToUTF16(1252, input)); | ||||
|     return UTF16ToUTF8(CPToUTF16(1252, input)); | ||||
| } | ||||
| 
 | ||||
| #else | ||||
|  | @ -449,83 +449,83 @@ std::string CP1252ToUTF8(const std::string& input) | |||
| template <typename T> | ||||
| std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& input) | ||||
| { | ||||
| 	std::string result; | ||||
|     std::string result; | ||||
| 
 | ||||
| 	iconv_t const conv_desc = iconv_open("UTF-8", fromcode); | ||||
| 	if ((iconv_t)-1 == conv_desc) | ||||
| 	{ | ||||
| 		ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno)); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		size_t const in_bytes = sizeof(T) * input.size(); | ||||
| 		size_t const out_buffer_size = 4 * in_bytes; | ||||
|     iconv_t const conv_desc = iconv_open("UTF-8", fromcode); | ||||
|     if ((iconv_t)-1 == conv_desc) | ||||
|     { | ||||
|         ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno)); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         size_t const in_bytes = sizeof(T) * input.size(); | ||||
|         size_t const out_buffer_size = 4 * in_bytes; | ||||
| 
 | ||||
| 		std::string out_buffer; | ||||
| 		out_buffer.resize(out_buffer_size); | ||||
|         std::string out_buffer; | ||||
|         out_buffer.resize(out_buffer_size); | ||||
| 
 | ||||
| 		auto src_buffer = &input[0]; | ||||
| 		size_t src_bytes = in_bytes; | ||||
| 		auto dst_buffer = &out_buffer[0]; | ||||
| 		size_t dst_bytes = out_buffer.size(); | ||||
|         auto src_buffer = &input[0]; | ||||
|         size_t src_bytes = in_bytes; | ||||
|         auto dst_buffer = &out_buffer[0]; | ||||
|         size_t dst_bytes = out_buffer.size(); | ||||
| 
 | ||||
| 		while (src_bytes != 0) | ||||
| 		{ | ||||
| 			size_t const iconv_result = iconv(conv_desc, (char**)(&src_buffer), &src_bytes, | ||||
| 				&dst_buffer, &dst_bytes); | ||||
|         while (src_bytes != 0) | ||||
|         { | ||||
|             size_t const iconv_result = iconv(conv_desc, (char**)(&src_buffer), &src_bytes, | ||||
|                 &dst_buffer, &dst_bytes); | ||||
| 
 | ||||
| 			if ((size_t)-1 == iconv_result) | ||||
| 			{ | ||||
| 				if (EILSEQ == errno || EINVAL == errno) | ||||
| 				{ | ||||
| 					// Try to skip the bad character
 | ||||
| 					if (src_bytes != 0) | ||||
| 					{ | ||||
| 						--src_bytes; | ||||
| 						++src_buffer; | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno)); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|             if ((size_t)-1 == iconv_result) | ||||
|             { | ||||
|                 if (EILSEQ == errno || EINVAL == errno) | ||||
|                 { | ||||
|                     // Try to skip the bad character
 | ||||
|                     if (src_bytes != 0) | ||||
|                     { | ||||
|                         --src_bytes; | ||||
|                         ++src_buffer; | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno)); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 		out_buffer.resize(out_buffer_size - dst_bytes); | ||||
| 		out_buffer.swap(result); | ||||
| 		 | ||||
| 		iconv_close(conv_desc); | ||||
| 	} | ||||
| 	 | ||||
| 	return result; | ||||
|         out_buffer.resize(out_buffer_size - dst_bytes); | ||||
|         out_buffer.swap(result); | ||||
|          | ||||
|         iconv_close(conv_desc); | ||||
|     } | ||||
|      | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| std::string CP1252ToUTF8(const std::string& input) | ||||
| { | ||||
| 	//return CodeToUTF8("CP1252//TRANSLIT", input);
 | ||||
| 	//return CodeToUTF8("CP1252//IGNORE", input);
 | ||||
| 	return CodeToUTF8("CP1252", input); | ||||
|     //return CodeToUTF8("CP1252//TRANSLIT", input);
 | ||||
|     //return CodeToUTF8("CP1252//IGNORE", input);
 | ||||
|     return CodeToUTF8("CP1252", input); | ||||
| } | ||||
| 
 | ||||
| std::string SHIFTJISToUTF8(const std::string& input) | ||||
| { | ||||
| 	//return CodeToUTF8("CP932", input);
 | ||||
| 	return CodeToUTF8("SJIS", input); | ||||
|     //return CodeToUTF8("CP932", input);
 | ||||
|     return CodeToUTF8("SJIS", input); | ||||
| } | ||||
| 
 | ||||
| std::string UTF16ToUTF8(const std::wstring& input) | ||||
| { | ||||
| 	std::string result = | ||||
| 	//	CodeToUTF8("UCS-2", input);
 | ||||
| 	//	CodeToUTF8("UCS-2LE", input);
 | ||||
| 	//	CodeToUTF8("UTF-16", input);
 | ||||
| 		CodeToUTF8("UTF-16LE", input); | ||||
|     std::string result = | ||||
|     //    CodeToUTF8("UCS-2", input);
 | ||||
|     //    CodeToUTF8("UCS-2LE", input);
 | ||||
|     //    CodeToUTF8("UTF-16", input);
 | ||||
|         CodeToUTF8("UTF-16LE", input); | ||||
| 
 | ||||
| 	// TODO: why is this needed?
 | ||||
| 	result.erase(std::remove(result.begin(), result.end(), 0x00), result.end()); | ||||
| 	return result; | ||||
|     // TODO: why is this needed?
 | ||||
|     result.erase(std::remove(result.begin(), result.end(), 0x00), result.end()); | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -21,10 +21,10 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar | |||
| template<size_t Count> | ||||
| inline void CharArrayFromFormat(char (& out)[Count], const char* format, ...) | ||||
| { | ||||
| 	va_list args; | ||||
| 	va_start(args, format); | ||||
| 	CharArrayFromFormatV(out, Count, format, args); | ||||
| 	va_end(args); | ||||
|     va_list args; | ||||
|     va_start(args, format); | ||||
|     CharArrayFromFormatV(out, Count, format, args); | ||||
|     va_end(args); | ||||
| } | ||||
| 
 | ||||
| // Good
 | ||||
|  | @ -37,15 +37,15 @@ std::string StripQuotes(const std::string &s); | |||
| template <typename I> | ||||
| std::string ThousandSeparate(I value, int spaces = 0) | ||||
| { | ||||
| 	std::ostringstream oss; | ||||
|     std::ostringstream oss; | ||||
| 
 | ||||
| // std::locale("") seems to be broken on many platforms
 | ||||
| #if defined _WIN32 || (defined __linux__ && !defined __clang__) | ||||
| 	oss.imbue(std::locale("")); | ||||
|     oss.imbue(std::locale("")); | ||||
| #endif | ||||
| 	oss << std::setw(spaces) << value; | ||||
|     oss << std::setw(spaces) << value; | ||||
| 
 | ||||
| 	return oss.str(); | ||||
|     return oss.str(); | ||||
| } | ||||
| 
 | ||||
| std::string StringFromInt(int value); | ||||
|  | @ -57,16 +57,16 @@ bool TryParse(const std::string &str, u32 *output); | |||
| template <typename N> | ||||
| static bool TryParse(const std::string &str, N *const output) | ||||
| { | ||||
| 	std::istringstream iss(str); | ||||
| 	 | ||||
| 	N tmp = 0; | ||||
| 	if (iss >> tmp) | ||||
| 	{ | ||||
| 		*output = tmp; | ||||
| 		return true; | ||||
| 	} | ||||
| 	else | ||||
| 		return false; | ||||
|     std::istringstream iss(str); | ||||
|      | ||||
|     N tmp = 0; | ||||
|     if (iss >> tmp) | ||||
|     { | ||||
|         *output = tmp; | ||||
|         return true; | ||||
|     } | ||||
|     else | ||||
|         return false; | ||||
| } | ||||
| 
 | ||||
| // TODO: kill this
 | ||||
|  |  | |||
|  | @ -63,426 +63,426 @@ | |||
| 
 | ||||
| template <typename T, typename F> | ||||
| struct swap_struct_t { | ||||
| 	typedef swap_struct_t<T, F> swapped_t; | ||||
|     typedef swap_struct_t<T, F> swapped_t; | ||||
| 
 | ||||
| protected: | ||||
| 	T value; | ||||
|     T value; | ||||
| 
 | ||||
| 	static T swap(T v) { | ||||
| 		return F::swap(v); | ||||
| 	} | ||||
|     static T swap(T v) { | ||||
|         return F::swap(v); | ||||
|     } | ||||
| public: | ||||
| 	T const swap() const { | ||||
| 		return swap(value); | ||||
|     T const swap() const { | ||||
|         return swap(value); | ||||
| 
 | ||||
| 	} | ||||
| 	swap_struct_t() : value((T)0) {} | ||||
| 	swap_struct_t(const T &v): value(swap(v)) {} | ||||
|     } | ||||
|     swap_struct_t() : value((T)0) {} | ||||
|     swap_struct_t(const T &v): value(swap(v)) {} | ||||
| 
 | ||||
| 	template <typename S> | ||||
| 	swapped_t& operator=(const S &source) { | ||||
| 		value = swap((T)source); | ||||
| 		return *this; | ||||
| 	} | ||||
|     template <typename S> | ||||
|     swapped_t& operator=(const S &source) { | ||||
|         value = swap((T)source); | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
| 	operator long() const { return (long)swap(); }	 | ||||
| 	operator s8() const { return (s8)swap(); } | ||||
| 	operator u8() const { return (u8)swap(); } | ||||
| 	operator s16() const { return (s16)swap(); } | ||||
| 	operator u16() const { return (u16)swap(); } | ||||
| 	operator s32() const { return (s32)swap(); } | ||||
| 	operator u32() const { return (u32)swap(); } | ||||
| 	operator s64() const { return (s64)swap(); } | ||||
| 	operator u64() const { return (u64)swap(); } | ||||
| 	operator float() const { return (float)swap(); } | ||||
| 	operator double() const { return (double)swap(); } | ||||
|     operator long() const { return (long)swap(); }     | ||||
|     operator s8() const { return (s8)swap(); } | ||||
|     operator u8() const { return (u8)swap(); } | ||||
|     operator s16() const { return (s16)swap(); } | ||||
|     operator u16() const { return (u16)swap(); } | ||||
|     operator s32() const { return (s32)swap(); } | ||||
|     operator u32() const { return (u32)swap(); } | ||||
|     operator s64() const { return (s64)swap(); } | ||||
|     operator u64() const { return (u64)swap(); } | ||||
|     operator float() const { return (float)swap(); } | ||||
|     operator double() const { return (double)swap(); } | ||||
| 
 | ||||
| 	// +v
 | ||||
| 	swapped_t operator +() const { | ||||
| 		return +swap(); | ||||
| 	} | ||||
| 	// -v
 | ||||
| 	swapped_t operator -() const { | ||||
| 		return -swap(); | ||||
| 	} | ||||
|     // +v
 | ||||
|     swapped_t operator +() const { | ||||
|         return +swap(); | ||||
|     } | ||||
|     // -v
 | ||||
|     swapped_t operator -() const { | ||||
|         return -swap(); | ||||
|     } | ||||
| 
 | ||||
| 	// v / 5
 | ||||
| 	swapped_t operator/(const swapped_t &i) const { | ||||
| 		return swap() / i.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t operator/(const S &i) const { | ||||
| 		return swap() / i; | ||||
| 	} | ||||
|     // v / 5
 | ||||
|     swapped_t operator/(const swapped_t &i) const { | ||||
|         return swap() / i.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t operator/(const S &i) const { | ||||
|         return swap() / i; | ||||
|     } | ||||
| 
 | ||||
| 	// v * 5
 | ||||
| 	swapped_t operator*(const swapped_t &i) const { | ||||
| 		return swap() * i.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t operator*(const S &i) const { | ||||
| 		return swap() * i; | ||||
| 	} | ||||
|     // v * 5
 | ||||
|     swapped_t operator*(const swapped_t &i) const { | ||||
|         return swap() * i.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t operator*(const S &i) const { | ||||
|         return swap() * i; | ||||
|     } | ||||
| 
 | ||||
| 	// v + 5
 | ||||
| 	swapped_t operator+(const swapped_t &i) const { | ||||
| 		return swap() + i.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t operator+(const S &i) const { | ||||
| 		return swap() + (T)i; | ||||
| 	} | ||||
| 	// v - 5
 | ||||
| 	swapped_t operator-(const swapped_t &i) const { | ||||
| 		return swap() - i.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t operator-(const S &i) const { | ||||
| 		return swap() - (T)i; | ||||
| 	} | ||||
|     // v + 5
 | ||||
|     swapped_t operator+(const swapped_t &i) const { | ||||
|         return swap() + i.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t operator+(const S &i) const { | ||||
|         return swap() + (T)i; | ||||
|     } | ||||
|     // v - 5
 | ||||
|     swapped_t operator-(const swapped_t &i) const { | ||||
|         return swap() - i.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t operator-(const S &i) const { | ||||
|         return swap() - (T)i; | ||||
|     } | ||||
| 
 | ||||
| 	// v += 5
 | ||||
| 	swapped_t& operator+=(const swapped_t &i) { | ||||
| 		value = swap(swap() + i.swap()); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t& operator+=(const S &i) { | ||||
| 		value = swap(swap() + (T)i); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	// v -= 5
 | ||||
| 	swapped_t& operator-=(const swapped_t &i) { | ||||
| 		value = swap(swap() - i.swap()); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t& operator-=(const S &i) { | ||||
| 		value = swap(swap() - (T)i); | ||||
| 		return *this; | ||||
| 	} | ||||
|     // v += 5
 | ||||
|     swapped_t& operator+=(const swapped_t &i) { | ||||
|         value = swap(swap() + i.swap()); | ||||
|         return *this; | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t& operator+=(const S &i) { | ||||
|         value = swap(swap() + (T)i); | ||||
|         return *this; | ||||
|     } | ||||
|     // v -= 5
 | ||||
|     swapped_t& operator-=(const swapped_t &i) { | ||||
|         value = swap(swap() - i.swap()); | ||||
|         return *this; | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t& operator-=(const S &i) { | ||||
|         value = swap(swap() - (T)i); | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
| 	// ++v
 | ||||
| 	swapped_t& operator++() { | ||||
| 		value = swap(swap()+1); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	// --v
 | ||||
| 	swapped_t& operator--()  { | ||||
| 		value = swap(swap()-1); | ||||
| 		return *this; | ||||
| 	} | ||||
|     // ++v
 | ||||
|     swapped_t& operator++() { | ||||
|         value = swap(swap()+1); | ||||
|         return *this; | ||||
|     } | ||||
|     // --v
 | ||||
|     swapped_t& operator--()  { | ||||
|         value = swap(swap()-1); | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
| 	// v++
 | ||||
| 	swapped_t operator++(int) { | ||||
| 		swapped_t old = *this; | ||||
| 		value = swap(swap()+1); | ||||
| 		return old; | ||||
| 	} | ||||
| 	// v--
 | ||||
| 	swapped_t operator--(int) { | ||||
| 		swapped_t old = *this; | ||||
| 		value = swap(swap()-1); | ||||
| 		return old; | ||||
| 	} | ||||
| 	// Comparaison
 | ||||
| 	// v == i
 | ||||
| 	bool operator==(const swapped_t &i) const { | ||||
| 		return swap() == i.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	bool operator==(const S &i) const { | ||||
| 		return swap() == i; | ||||
| 	} | ||||
|     // v++
 | ||||
|     swapped_t operator++(int) { | ||||
|         swapped_t old = *this; | ||||
|         value = swap(swap()+1); | ||||
|         return old; | ||||
|     } | ||||
|     // v--
 | ||||
|     swapped_t operator--(int) { | ||||
|         swapped_t old = *this; | ||||
|         value = swap(swap()-1); | ||||
|         return old; | ||||
|     } | ||||
|     // Comparaison
 | ||||
|     // v == i
 | ||||
|     bool operator==(const swapped_t &i) const { | ||||
|         return swap() == i.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     bool operator==(const S &i) const { | ||||
|         return swap() == i; | ||||
|     } | ||||
| 
 | ||||
| 	// v != i
 | ||||
| 	bool operator!=(const swapped_t &i) const { | ||||
| 		return swap() != i.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	bool operator!=(const S &i) const { | ||||
| 		return swap() != i; | ||||
| 	} | ||||
|     // v != i
 | ||||
|     bool operator!=(const swapped_t &i) const { | ||||
|         return swap() != i.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     bool operator!=(const S &i) const { | ||||
|         return swap() != i; | ||||
|     } | ||||
| 
 | ||||
| 	// v > i
 | ||||
| 	bool operator>(const swapped_t &i) const { | ||||
| 		return swap() > i.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	bool operator>(const S &i) const { | ||||
| 		return swap() > i; | ||||
| 	} | ||||
|     // v > i
 | ||||
|     bool operator>(const swapped_t &i) const { | ||||
|         return swap() > i.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     bool operator>(const S &i) const { | ||||
|         return swap() > i; | ||||
|     } | ||||
| 
 | ||||
| 	// v < i
 | ||||
| 	bool operator<(const swapped_t &i) const { | ||||
| 		return swap() < i.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	bool operator<(const S &i) const { | ||||
| 		return swap() < i; | ||||
| 	} | ||||
|     // v < i
 | ||||
|     bool operator<(const swapped_t &i) const { | ||||
|         return swap() < i.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     bool operator<(const S &i) const { | ||||
|         return swap() < i; | ||||
|     } | ||||
| 
 | ||||
| 	// v >= i
 | ||||
| 	bool operator>=(const swapped_t &i) const { | ||||
| 		return swap() >= i.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	bool operator>=(const S &i) const { | ||||
| 		return swap() >= i; | ||||
| 	} | ||||
|     // v >= i
 | ||||
|     bool operator>=(const swapped_t &i) const { | ||||
|         return swap() >= i.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     bool operator>=(const S &i) const { | ||||
|         return swap() >= i; | ||||
|     } | ||||
| 
 | ||||
| 	// v <= i
 | ||||
| 	bool operator<=(const swapped_t &i) const { | ||||
| 		return swap() <= i.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	bool operator<=(const S &i) const { | ||||
| 		return swap() <= i; | ||||
| 	} | ||||
|     // v <= i
 | ||||
|     bool operator<=(const swapped_t &i) const { | ||||
|         return swap() <= i.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     bool operator<=(const S &i) const { | ||||
|         return swap() <= i; | ||||
|     } | ||||
| 
 | ||||
| 	// logical
 | ||||
| 	swapped_t operator !() const { | ||||
| 		return !swap(); | ||||
| 	} | ||||
|     // logical
 | ||||
|     swapped_t operator !() const { | ||||
|         return !swap(); | ||||
|     } | ||||
| 
 | ||||
| 	// bitmath
 | ||||
| 	swapped_t operator ~() const { | ||||
| 		return ~swap(); | ||||
| 	} | ||||
|     // bitmath
 | ||||
|     swapped_t operator ~() const { | ||||
|         return ~swap(); | ||||
|     } | ||||
| 
 | ||||
| 	swapped_t operator &(const swapped_t &b) const { | ||||
| 		return swap() & b.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t operator &(const S &b) const { | ||||
| 		return swap() & b; | ||||
| 	} | ||||
| 	swapped_t& operator &=(const swapped_t &b) { | ||||
| 		value = swap(swap() & b.swap()); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t& operator &=(const S b) { | ||||
| 		value = swap(swap() & b); | ||||
| 		return *this; | ||||
| 	} | ||||
|     swapped_t operator &(const swapped_t &b) const { | ||||
|         return swap() & b.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t operator &(const S &b) const { | ||||
|         return swap() & b; | ||||
|     } | ||||
|     swapped_t& operator &=(const swapped_t &b) { | ||||
|         value = swap(swap() & b.swap()); | ||||
|         return *this; | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t& operator &=(const S b) { | ||||
|         value = swap(swap() & b); | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
| 	swapped_t operator |(const swapped_t &b) const { | ||||
| 		return swap() | b.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t operator |(const S &b) const { | ||||
| 		return swap() | b; | ||||
| 	} | ||||
| 	swapped_t& operator |=(const swapped_t &b) { | ||||
| 		value = swap(swap() | b.swap()); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t& operator |=(const S &b) { | ||||
| 		value = swap(swap() | b); | ||||
| 		return *this; | ||||
| 	} | ||||
|     swapped_t operator |(const swapped_t &b) const { | ||||
|         return swap() | b.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t operator |(const S &b) const { | ||||
|         return swap() | b; | ||||
|     } | ||||
|     swapped_t& operator |=(const swapped_t &b) { | ||||
|         value = swap(swap() | b.swap()); | ||||
|         return *this; | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t& operator |=(const S &b) { | ||||
|         value = swap(swap() | b); | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
| 	swapped_t operator ^(const swapped_t &b) const { | ||||
| 		return swap() ^ b.swap(); | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t operator ^(const S &b) const { | ||||
| 		return swap() ^ b; | ||||
| 	} | ||||
| 	swapped_t& operator ^=(const swapped_t &b) { | ||||
| 		value = swap(swap() ^ b.swap()); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t& operator ^=(const S &b) { | ||||
| 		value = swap(swap() ^ b); | ||||
| 		return *this; | ||||
| 	} | ||||
|     swapped_t operator ^(const swapped_t &b) const { | ||||
|         return swap() ^ b.swap(); | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t operator ^(const S &b) const { | ||||
|         return swap() ^ b; | ||||
|     } | ||||
|     swapped_t& operator ^=(const swapped_t &b) { | ||||
|         value = swap(swap() ^ b.swap()); | ||||
|         return *this; | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t& operator ^=(const S &b) { | ||||
|         value = swap(swap() ^ b); | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
| 	template <typename S> | ||||
| 	swapped_t operator <<(const S &b) const { | ||||
| 		return swap() << b; | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t& operator <<=(const S &b) const { | ||||
| 		value = swap(swap() << b); | ||||
| 		return *this; | ||||
| 	} | ||||
|     template <typename S> | ||||
|     swapped_t operator <<(const S &b) const { | ||||
|         return swap() << b; | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t& operator <<=(const S &b) const { | ||||
|         value = swap(swap() << b); | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
| 	template <typename S> | ||||
| 	swapped_t operator >>(const S &b) const { | ||||
| 		return swap() >> b; | ||||
| 	} | ||||
| 	template <typename S> | ||||
| 	swapped_t& operator >>=(const S &b) const { | ||||
| 		value = swap(swap() >> b); | ||||
| 		return *this; | ||||
| 	} | ||||
|     template <typename S> | ||||
|     swapped_t operator >>(const S &b) const { | ||||
|         return swap() >> b; | ||||
|     } | ||||
|     template <typename S> | ||||
|     swapped_t& operator >>=(const S &b) const { | ||||
|         value = swap(swap() >> b); | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
| 	// Member
 | ||||
| 	/** todo **/ | ||||
|     // Member
 | ||||
|     /** todo **/ | ||||
| 
 | ||||
| 
 | ||||
| 	// Arithmetics
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend S operator+(const S &p, const swapped_t v); | ||||
|     // Arithmetics
 | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend S operator+(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend S operator-(const S &p, const swapped_t v); | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend S operator-(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend S operator/(const S &p, const swapped_t v); | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend S operator/(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend S operator*(const S &p, const swapped_t v); | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend S operator*(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend S operator%(const S &p, const swapped_t v); | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend S operator%(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	// Arithmetics + assignements
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend S operator+=(const S &p, const swapped_t v); | ||||
|     // Arithmetics + assignements
 | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend S operator+=(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend S operator-=(const S &p, const swapped_t v); | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend S operator-=(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	// Bitmath
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend S operator&(const S &p, const swapped_t v); | ||||
|     // Bitmath
 | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend S operator&(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	// Comparison
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend bool operator<(const S &p, const swapped_t v); | ||||
|     // Comparison
 | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend bool operator<(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend bool operator>(const S &p, const swapped_t v); | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend bool operator>(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend bool operator<=(const S &p, const swapped_t v); | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend bool operator<=(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend bool operator>=(const S &p, const swapped_t v); | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend bool operator>=(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend bool operator!=(const S &p, const swapped_t v); | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend bool operator!=(const S &p, const swapped_t v); | ||||
| 
 | ||||
| 	template <typename S, typename T2, typename F2> | ||||
| 	friend bool operator==(const S &p, const swapped_t v); | ||||
|     template <typename S, typename T2, typename F2> | ||||
|     friend bool operator==(const S &p, const swapped_t v); | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| // Arithmetics
 | ||||
| template <typename S, typename T, typename F> | ||||
| S operator+(const S &i, const swap_struct_t<T, F> v) { | ||||
| 	return i + v.swap(); | ||||
|     return i + v.swap(); | ||||
| } | ||||
| 
 | ||||
| template <typename S, typename T, typename F> | ||||
| S operator-(const S &i, const swap_struct_t<T, F> v) { | ||||
| 	return i - v.swap(); | ||||
|     return i - v.swap(); | ||||
| } | ||||
| 
 | ||||
| template <typename S, typename T, typename F> | ||||
| S operator/(const S &i, const swap_struct_t<T, F> v) { | ||||
| 	return i / v.swap(); | ||||
|     return i / v.swap(); | ||||
| } | ||||
| 
 | ||||
| template <typename S, typename T, typename F> | ||||
| S operator*(const S &i, const swap_struct_t<T, F> v) { | ||||
| 	return i * v.swap(); | ||||
|     return i * v.swap(); | ||||
| } | ||||
| 
 | ||||
| template <typename S, typename T, typename F> | ||||
| S operator%(const S &i, const swap_struct_t<T, F> v) { | ||||
| 	return i % v.swap(); | ||||
|     return i % v.swap(); | ||||
| } | ||||
| 
 | ||||
| // Arithmetics + assignements
 | ||||
| template <typename S, typename T, typename F> | ||||
| S &operator+=(S &i, const swap_struct_t<T, F> v) { | ||||
| 	i += v.swap(); | ||||
| 	return i; | ||||
|     i += v.swap(); | ||||
|     return i; | ||||
| } | ||||
| 
 | ||||
| template <typename S, typename T, typename F> | ||||
| S &operator-=(S &i, const swap_struct_t<T, F> v) { | ||||
| 	i -= v.swap(); | ||||
| 	return i; | ||||
|     i -= v.swap(); | ||||
|     return i; | ||||
| } | ||||
| 
 | ||||
| // Logical
 | ||||
| template <typename S, typename T, typename F> | ||||
| S operator&(const S &i, const swap_struct_t<T, F> v) { | ||||
| 	return i & v.swap(); | ||||
|     return i & v.swap(); | ||||
| } | ||||
| 
 | ||||
| template <typename S, typename T, typename F> | ||||
| S operator&(const swap_struct_t<T, F> v, const S &i) { | ||||
| 	return (S)(v.swap() & i); | ||||
|     return (S)(v.swap() & i); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Comparaison
 | ||||
| template <typename S, typename T, typename F> | ||||
| bool operator<(const S &p, const swap_struct_t<T, F> v) { | ||||
| 	return p < v.swap(); | ||||
|     return p < v.swap(); | ||||
| } | ||||
| template <typename S, typename T, typename F> | ||||
| bool operator>(const S &p, const swap_struct_t<T, F> v) { | ||||
| 	return p > v.swap(); | ||||
|     return p > v.swap(); | ||||
| } | ||||
| template <typename S, typename T, typename F> | ||||
| bool operator<=(const S &p, const swap_struct_t<T, F> v) { | ||||
| 	return p <= v.swap(); | ||||
|     return p <= v.swap(); | ||||
| } | ||||
| template <typename S, typename T, typename F> | ||||
| bool operator>=(const S &p, const swap_struct_t<T, F> v) { | ||||
| 	return p >= v.swap(); | ||||
|     return p >= v.swap(); | ||||
| } | ||||
| template <typename S, typename T, typename F> | ||||
| bool operator!=(const S &p, const swap_struct_t<T, F> v) { | ||||
| 	return p != v.swap(); | ||||
|     return p != v.swap(); | ||||
| } | ||||
| template <typename S, typename T, typename F> | ||||
| bool operator==(const S &p, const swap_struct_t<T, F> v) { | ||||
| 	return p == v.swap(); | ||||
|     return p == v.swap(); | ||||
| } | ||||
| 
 | ||||
| template <typename T> | ||||
| struct swap_64_t { | ||||
| 	static T swap(T x) { | ||||
| 		return (T)bswap64(*(u64 *)&x); | ||||
| 	} | ||||
|     static T swap(T x) { | ||||
|         return (T)bswap64(*(u64 *)&x); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| template <typename T> | ||||
| struct swap_32_t { | ||||
| 	static T swap(T x) { | ||||
| 		return (T)bswap32(*(u32 *)&x); | ||||
| 	} | ||||
|     static T swap(T x) { | ||||
|         return (T)bswap32(*(u32 *)&x); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| template <typename T> | ||||
| struct swap_16_t { | ||||
| 	static T swap(T x) { | ||||
| 		return (T)bswap16(*(u16 *)&x); | ||||
| 	} | ||||
|     static T swap(T x) { | ||||
|         return (T)bswap16(*(u16 *)&x); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| template <typename T> | ||||
| struct swap_float_t { | ||||
| 	static T swap(T x) { | ||||
| 		return (T)bswapf(*(float *)&x); | ||||
| 	} | ||||
|     static T swap(T x) { | ||||
|         return (T)bswapf(*(float *)&x); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| template <typename T> | ||||
| struct swap_double_t { | ||||
| 	static T swap(T x) { | ||||
| 		return (T)bswapd(*(double *)&x); | ||||
| 	} | ||||
|     static T swap(T x) { | ||||
|         return (T)bswapd(*(double *)&x); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| #if COMMON_LITTLE_ENDIAN | ||||
|  |  | |||
|  | @ -21,110 +21,110 @@ namespace Common | |||
| int CurrentThreadId() | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	return GetCurrentThreadId(); | ||||
|     return GetCurrentThreadId(); | ||||
| #elif defined __APPLE__ | ||||
| 	return mach_thread_self(); | ||||
|     return mach_thread_self(); | ||||
| #else | ||||
| 	return 0; | ||||
|     return 0; | ||||
| #endif | ||||
| } | ||||
| 	 | ||||
|      | ||||
| #ifdef _WIN32 | ||||
| 
 | ||||
| void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) | ||||
| { | ||||
| 	SetThreadAffinityMask(thread, mask); | ||||
|     SetThreadAffinityMask(thread, mask); | ||||
| } | ||||
| 
 | ||||
| void SetCurrentThreadAffinity(u32 mask) | ||||
| { | ||||
| 	SetThreadAffinityMask(GetCurrentThread(), mask); | ||||
|     SetThreadAffinityMask(GetCurrentThread(), mask); | ||||
| } | ||||
| 
 | ||||
| // Supporting functions
 | ||||
| void SleepCurrentThread(int ms) | ||||
| { | ||||
| 	Sleep(ms); | ||||
|     Sleep(ms); | ||||
| } | ||||
| 
 | ||||
| void SwitchCurrentThread() | ||||
| { | ||||
| 	SwitchToThread(); | ||||
|     SwitchToThread(); | ||||
| } | ||||
| 
 | ||||
| // Sets the debugger-visible name of the current thread.
 | ||||
| // Uses undocumented (actually, it is now documented) trick.
 | ||||
| // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsdebug/html/vxtsksettingthreadname.asp
 | ||||
| 	 | ||||
|      | ||||
| // This is implemented much nicer in upcoming msvc++, see:
 | ||||
| // http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.100).aspx
 | ||||
| void SetCurrentThreadName(const char* szThreadName) | ||||
| { | ||||
| 	static const DWORD MS_VC_EXCEPTION = 0x406D1388; | ||||
|     static const DWORD MS_VC_EXCEPTION = 0x406D1388; | ||||
| 
 | ||||
| 	#pragma pack(push,8) | ||||
| 	struct THREADNAME_INFO | ||||
| 	{ | ||||
| 		DWORD dwType; // must be 0x1000
 | ||||
| 		LPCSTR szName; // pointer to name (in user addr space)
 | ||||
| 		DWORD dwThreadID; // thread ID (-1=caller thread)
 | ||||
| 		DWORD dwFlags; // reserved for future use, must be zero
 | ||||
| 	} info; | ||||
| 	#pragma pack(pop) | ||||
|     #pragma pack(push,8) | ||||
|     struct THREADNAME_INFO | ||||
|     { | ||||
|         DWORD dwType; // must be 0x1000
 | ||||
|         LPCSTR szName; // pointer to name (in user addr space)
 | ||||
|         DWORD dwThreadID; // thread ID (-1=caller thread)
 | ||||
|         DWORD dwFlags; // reserved for future use, must be zero
 | ||||
|     } info; | ||||
|     #pragma pack(pop) | ||||
| 
 | ||||
| 	info.dwType = 0x1000; | ||||
| 	info.szName = szThreadName; | ||||
| 	info.dwThreadID = -1; //dwThreadID;
 | ||||
| 	info.dwFlags = 0; | ||||
|     info.dwType = 0x1000; | ||||
|     info.szName = szThreadName; | ||||
|     info.dwThreadID = -1; //dwThreadID;
 | ||||
|     info.dwFlags = 0; | ||||
| 
 | ||||
| 	__try | ||||
| 	{ | ||||
| 		RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info); | ||||
| 	} | ||||
| 	__except(EXCEPTION_CONTINUE_EXECUTION) | ||||
| 	{} | ||||
|     __try | ||||
|     { | ||||
|         RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info); | ||||
|     } | ||||
|     __except(EXCEPTION_CONTINUE_EXECUTION) | ||||
|     {} | ||||
| } | ||||
| 	 | ||||
|      | ||||
| #else // !WIN32, so must be POSIX threads
 | ||||
| 
 | ||||
| void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) | ||||
| { | ||||
| #ifdef __APPLE__ | ||||
| 	thread_policy_set(pthread_mach_thread_np(thread), | ||||
| 		THREAD_AFFINITY_POLICY, (integer_t *)&mask, 1); | ||||
|     thread_policy_set(pthread_mach_thread_np(thread), | ||||
|         THREAD_AFFINITY_POLICY, (integer_t *)&mask, 1); | ||||
| #elif (defined __linux__ || defined BSD4_4) && !(defined ANDROID) | ||||
| 	cpu_set_t cpu_set; | ||||
| 	CPU_ZERO(&cpu_set); | ||||
|     cpu_set_t cpu_set; | ||||
|     CPU_ZERO(&cpu_set); | ||||
| 
 | ||||
| 	for (int i = 0; i != sizeof(mask) * 8; ++i) | ||||
| 		if ((mask >> i) & 1) | ||||
| 			CPU_SET(i, &cpu_set); | ||||
|     for (int i = 0; i != sizeof(mask) * 8; ++i) | ||||
|         if ((mask >> i) & 1) | ||||
|             CPU_SET(i, &cpu_set); | ||||
| 
 | ||||
| 	pthread_setaffinity_np(thread, sizeof(cpu_set), &cpu_set); | ||||
|     pthread_setaffinity_np(thread, sizeof(cpu_set), &cpu_set); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void SetCurrentThreadAffinity(u32 mask) | ||||
| { | ||||
| 	SetThreadAffinity(pthread_self(), mask); | ||||
|     SetThreadAffinity(pthread_self(), mask); | ||||
| } | ||||
| 
 | ||||
| void SleepCurrentThread(int ms) | ||||
| { | ||||
| 	usleep(1000 * ms); | ||||
|     usleep(1000 * ms); | ||||
| } | ||||
| 
 | ||||
| void SwitchCurrentThread() | ||||
| { | ||||
| 	usleep(1000 * 1); | ||||
|     usleep(1000 * 1); | ||||
| } | ||||
| 
 | ||||
| void SetCurrentThreadName(const char* szThreadName) | ||||
| { | ||||
| #ifdef __APPLE__ | ||||
| 	pthread_setname_np(szThreadName); | ||||
|     pthread_setname_np(szThreadName); | ||||
| #else | ||||
| 	pthread_setname_np(pthread_self(), szThreadName); | ||||
|     pthread_setname_np(pthread_self(), szThreadName); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,125 +32,125 @@ int CurrentThreadId(); | |||
| 
 | ||||
| void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask); | ||||
| void SetCurrentThreadAffinity(u32 mask); | ||||
| 	 | ||||
|      | ||||
| class Event | ||||
| { | ||||
| public: | ||||
| 	Event() | ||||
| 		: is_set(false) | ||||
| 	{}; | ||||
|     Event() | ||||
|         : is_set(false) | ||||
|     {}; | ||||
| 
 | ||||
| 	void Set() | ||||
| 	{ | ||||
| 		std::lock_guard<std::mutex> lk(m_mutex); | ||||
| 		if (!is_set) | ||||
| 		{ | ||||
| 			is_set = true; | ||||
| 			m_condvar.notify_one(); | ||||
| 		} | ||||
| 	} | ||||
|     void Set() | ||||
|     { | ||||
|         std::lock_guard<std::mutex> lk(m_mutex); | ||||
|         if (!is_set) | ||||
|         { | ||||
|             is_set = true; | ||||
|             m_condvar.notify_one(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	void Wait() | ||||
| 	{ | ||||
| 		std::unique_lock<std::mutex> lk(m_mutex); | ||||
| 		m_condvar.wait(lk, IsSet(this)); | ||||
| 		is_set = false; | ||||
| 	} | ||||
|     void Wait() | ||||
|     { | ||||
|         std::unique_lock<std::mutex> lk(m_mutex); | ||||
|         m_condvar.wait(lk, IsSet(this)); | ||||
|         is_set = false; | ||||
|     } | ||||
| 
 | ||||
| 	void Reset() | ||||
| 	{ | ||||
| 		std::unique_lock<std::mutex> lk(m_mutex); | ||||
| 		// no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration
 | ||||
| 		is_set = false; | ||||
| 	} | ||||
|     void Reset() | ||||
|     { | ||||
|         std::unique_lock<std::mutex> lk(m_mutex); | ||||
|         // no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration
 | ||||
|         is_set = false; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| 	class IsSet | ||||
| 	{ | ||||
| 	public: | ||||
| 		IsSet(const Event* ev) | ||||
| 			: m_event(ev) | ||||
| 		{} | ||||
|     class IsSet | ||||
|     { | ||||
|     public: | ||||
|         IsSet(const Event* ev) | ||||
|             : m_event(ev) | ||||
|         {} | ||||
| 
 | ||||
| 		bool operator()() | ||||
| 		{ | ||||
| 			return m_event->is_set; | ||||
| 		} | ||||
|         bool operator()() | ||||
|         { | ||||
|             return m_event->is_set; | ||||
|         } | ||||
| 
 | ||||
| 	private: | ||||
| 		const Event* const m_event; | ||||
| 	}; | ||||
|     private: | ||||
|         const Event* const m_event; | ||||
|     }; | ||||
| 
 | ||||
| 	volatile bool is_set; | ||||
| 	std::condition_variable m_condvar; | ||||
| 	std::mutex m_mutex; | ||||
|     volatile bool is_set; | ||||
|     std::condition_variable m_condvar; | ||||
|     std::mutex m_mutex; | ||||
| }; | ||||
| 
 | ||||
| // TODO: doesn't work on windows with (count > 2)
 | ||||
| class Barrier | ||||
| { | ||||
| public: | ||||
| 	Barrier(size_t count) | ||||
| 		: m_count(count), m_waiting(0) | ||||
| 	{} | ||||
|     Barrier(size_t count) | ||||
|         : m_count(count), m_waiting(0) | ||||
|     {} | ||||
| 
 | ||||
| 	// block until "count" threads call Sync()
 | ||||
| 	bool Sync() | ||||
| 	{ | ||||
| 		std::unique_lock<std::mutex> lk(m_mutex); | ||||
|     // block until "count" threads call Sync()
 | ||||
|     bool Sync() | ||||
|     { | ||||
|         std::unique_lock<std::mutex> lk(m_mutex); | ||||
| 
 | ||||
| 		// TODO: broken when next round of Sync()s
 | ||||
| 		// is entered before all waiting threads return from the notify_all
 | ||||
|         // TODO: broken when next round of Sync()s
 | ||||
|         // is entered before all waiting threads return from the notify_all
 | ||||
| 
 | ||||
| 		if (m_count == ++m_waiting) | ||||
| 		{ | ||||
| 			m_waiting = 0; | ||||
| 			m_condvar.notify_all(); | ||||
| 			return true; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			m_condvar.wait(lk, IsDoneWating(this)); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|         if (m_count == ++m_waiting) | ||||
|         { | ||||
|             m_waiting = 0; | ||||
|             m_condvar.notify_all(); | ||||
|             return true; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             m_condvar.wait(lk, IsDoneWating(this)); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| 	class IsDoneWating | ||||
| 	{ | ||||
| 	public: | ||||
| 		IsDoneWating(const Barrier* bar) | ||||
| 			: m_bar(bar) | ||||
| 		{} | ||||
|     class IsDoneWating | ||||
|     { | ||||
|     public: | ||||
|         IsDoneWating(const Barrier* bar) | ||||
|             : m_bar(bar) | ||||
|         {} | ||||
| 
 | ||||
| 		bool operator()() | ||||
| 		{ | ||||
| 			return (0 == m_bar->m_waiting); | ||||
| 		} | ||||
|         bool operator()() | ||||
|         { | ||||
|             return (0 == m_bar->m_waiting); | ||||
|         } | ||||
| 
 | ||||
| 	private: | ||||
| 		const Barrier* const m_bar; | ||||
| 	}; | ||||
|     private: | ||||
|         const Barrier* const m_bar; | ||||
|     }; | ||||
| 
 | ||||
| 	std::condition_variable m_condvar; | ||||
| 	std::mutex m_mutex; | ||||
| 	const size_t m_count; | ||||
| 	volatile size_t m_waiting; | ||||
|     std::condition_variable m_condvar; | ||||
|     std::mutex m_mutex; | ||||
|     const size_t m_count; | ||||
|     volatile size_t m_waiting; | ||||
| }; | ||||
| 	 | ||||
|      | ||||
| void SleepCurrentThread(int ms); | ||||
| void SwitchCurrentThread();	// On Linux, this is equal to sleep 1ms
 | ||||
| void SwitchCurrentThread();    // On Linux, this is equal to sleep 1ms
 | ||||
| 
 | ||||
| // Use this function during a spin-wait to make the current thread
 | ||||
| // relax while another thread is working. This may be more efficient
 | ||||
| // than using events because event functions use kernel calls.
 | ||||
| inline void YieldCPU() | ||||
| { | ||||
| 	std::this_thread::yield(); | ||||
|     std::this_thread::yield(); | ||||
| } | ||||
| 	 | ||||
|      | ||||
| void SetCurrentThreadName(const char *name); | ||||
| 	 | ||||
|      | ||||
| } // namespace Common
 | ||||
| 
 | ||||
| #endif // _THREAD_H_
 | ||||
|  |  | |||
|  | @ -24,23 +24,23 @@ | |||
| 
 | ||||
| class ThunkManager : public Gen::XCodeBlock | ||||
| { | ||||
| 	std::map<void *, const u8 *> thunks; | ||||
|     std::map<void *, const u8 *> thunks; | ||||
| 
 | ||||
| 	const u8 *save_regs; | ||||
| 	const u8 *load_regs; | ||||
|     const u8 *save_regs; | ||||
|     const u8 *load_regs; | ||||
| 
 | ||||
| public: | ||||
| 	ThunkManager() { | ||||
| 		Init(); | ||||
| 	} | ||||
| 	~ThunkManager() { | ||||
| 		Shutdown(); | ||||
| 	} | ||||
| 	void *ProtectFunction(void *function, int num_params); | ||||
|     ThunkManager() { | ||||
|         Init(); | ||||
|     } | ||||
|     ~ThunkManager() { | ||||
|         Shutdown(); | ||||
|     } | ||||
|     void *ProtectFunction(void *function, int num_params); | ||||
| private: | ||||
| 	void Init(); | ||||
| 	void Shutdown(); | ||||
| 	void Reset(); | ||||
|     void Init(); | ||||
|     void Shutdown(); | ||||
|     void Reset(); | ||||
| }; | ||||
| 
 | ||||
| #endif // _THUNK_H_
 | ||||
|  |  | |||
|  | @ -22,11 +22,11 @@ namespace Common | |||
| u32 Timer::GetTimeMs() | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	return timeGetTime(); | ||||
|     return timeGetTime(); | ||||
| #else | ||||
| 	struct timeval t; | ||||
| 	(void)gettimeofday(&t, NULL); | ||||
| 	return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); | ||||
|     struct timeval t; | ||||
|     (void)gettimeofday(&t, NULL); | ||||
|     return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  | @ -36,31 +36,31 @@ u32 Timer::GetTimeMs() | |||
| 
 | ||||
| // Set initial values for the class
 | ||||
| Timer::Timer() | ||||
| 	: m_LastTime(0), m_StartTime(0), m_Running(false) | ||||
|     : m_LastTime(0), m_StartTime(0), m_Running(false) | ||||
| { | ||||
| 	Update(); | ||||
|     Update(); | ||||
| } | ||||
| 
 | ||||
| // Write the starting time
 | ||||
| void Timer::Start() | ||||
| { | ||||
| 	m_StartTime = GetTimeMs(); | ||||
| 	m_Running = true; | ||||
|     m_StartTime = GetTimeMs(); | ||||
|     m_Running = true; | ||||
| } | ||||
| 
 | ||||
| // Stop the timer
 | ||||
| void Timer::Stop() | ||||
| { | ||||
| 	// Write the final time
 | ||||
| 	m_LastTime = GetTimeMs(); | ||||
| 	m_Running = false; | ||||
|     // Write the final time
 | ||||
|     m_LastTime = GetTimeMs(); | ||||
|     m_Running = false; | ||||
| } | ||||
| 
 | ||||
| // Update the last time variable
 | ||||
| void Timer::Update() | ||||
| { | ||||
| 	m_LastTime = GetTimeMs(); | ||||
| 	//TODO(ector) - QPF
 | ||||
|     m_LastTime = GetTimeMs(); | ||||
|     //TODO(ector) - QPF
 | ||||
| } | ||||
| 
 | ||||
| // -------------------------------------
 | ||||
|  | @ -70,125 +70,125 @@ void Timer::Update() | |||
| // Get the number of milliseconds since the last Update()
 | ||||
| u64 Timer::GetTimeDifference() | ||||
| { | ||||
| 	return GetTimeMs() - m_LastTime; | ||||
|     return GetTimeMs() - m_LastTime; | ||||
| } | ||||
| 
 | ||||
| // Add the time difference since the last Update() to the starting time.
 | ||||
| // This is used to compensate for a paused game.
 | ||||
| void Timer::AddTimeDifference() | ||||
| { | ||||
| 	m_StartTime += GetTimeDifference(); | ||||
|     m_StartTime += GetTimeDifference(); | ||||
| } | ||||
| 
 | ||||
| // Get the time elapsed since the Start()
 | ||||
| u64 Timer::GetTimeElapsed() | ||||
| { | ||||
| 	// If we have not started yet, return 1 (because then I don't
 | ||||
| 	// have to change the FPS calculation in CoreRerecording.cpp .
 | ||||
| 	if (m_StartTime == 0) return 1; | ||||
|     // If we have not started yet, return 1 (because then I don't
 | ||||
|     // have to change the FPS calculation in CoreRerecording.cpp .
 | ||||
|     if (m_StartTime == 0) return 1; | ||||
| 
 | ||||
| 	// Return the final timer time if the timer is stopped
 | ||||
| 	if (!m_Running) return (m_LastTime - m_StartTime); | ||||
|     // Return the final timer time if the timer is stopped
 | ||||
|     if (!m_Running) return (m_LastTime - m_StartTime); | ||||
| 
 | ||||
| 	return (GetTimeMs() - m_StartTime); | ||||
|     return (GetTimeMs() - m_StartTime); | ||||
| } | ||||
| 
 | ||||
| // Get the formatted time elapsed since the Start()
 | ||||
| std::string Timer::GetTimeElapsedFormatted() const | ||||
| { | ||||
| 	// If we have not started yet, return zero
 | ||||
| 	if (m_StartTime == 0) | ||||
| 		return "00:00:00:000"; | ||||
|     // If we have not started yet, return zero
 | ||||
|     if (m_StartTime == 0) | ||||
|         return "00:00:00:000"; | ||||
| 
 | ||||
| 	// The number of milliseconds since the start.
 | ||||
| 	// Use a different value if the timer is stopped.
 | ||||
| 	u64 Milliseconds; | ||||
| 	if (m_Running) | ||||
| 		Milliseconds = GetTimeMs() - m_StartTime; | ||||
| 	else | ||||
| 		Milliseconds = m_LastTime - m_StartTime; | ||||
| 	// Seconds
 | ||||
| 	u32 Seconds = (u32)(Milliseconds / 1000); | ||||
| 	// Minutes
 | ||||
| 	u32 Minutes = Seconds / 60; | ||||
| 	// Hours
 | ||||
| 	u32 Hours = Minutes / 60; | ||||
|     // The number of milliseconds since the start.
 | ||||
|     // Use a different value if the timer is stopped.
 | ||||
|     u64 Milliseconds; | ||||
|     if (m_Running) | ||||
|         Milliseconds = GetTimeMs() - m_StartTime; | ||||
|     else | ||||
|         Milliseconds = m_LastTime - m_StartTime; | ||||
|     // Seconds
 | ||||
|     u32 Seconds = (u32)(Milliseconds / 1000); | ||||
|     // Minutes
 | ||||
|     u32 Minutes = Seconds / 60; | ||||
|     // Hours
 | ||||
|     u32 Hours = Minutes / 60; | ||||
| 
 | ||||
| 	std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i", | ||||
| 		Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000); | ||||
| 	return TmpStr; | ||||
|     std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i", | ||||
|         Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000); | ||||
|     return TmpStr; | ||||
| } | ||||
| 
 | ||||
| // Get current time
 | ||||
| void Timer::IncreaseResolution() | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	timeBeginPeriod(1); | ||||
|     timeBeginPeriod(1); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void Timer::RestoreResolution() | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	timeEndPeriod(1); | ||||
|     timeEndPeriod(1); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| // Get the number of seconds since January 1 1970
 | ||||
| u64 Timer::GetTimeSinceJan1970() | ||||
| { | ||||
| 	time_t ltime; | ||||
| 	time(<ime); | ||||
| 	return((u64)ltime); | ||||
|     time_t ltime; | ||||
|     time(<ime); | ||||
|     return((u64)ltime); | ||||
| } | ||||
| 
 | ||||
| u64 Timer::GetLocalTimeSinceJan1970() | ||||
| { | ||||
| 	time_t sysTime, tzDiff, tzDST; | ||||
| 	struct tm * gmTime; | ||||
|     time_t sysTime, tzDiff, tzDST; | ||||
|     struct tm * gmTime; | ||||
| 
 | ||||
| 	time(&sysTime); | ||||
|     time(&sysTime); | ||||
| 
 | ||||
| 	// Account for DST where needed
 | ||||
| 	gmTime = localtime(&sysTime); | ||||
| 	if(gmTime->tm_isdst == 1) | ||||
| 		tzDST = 3600; | ||||
| 	else | ||||
| 		tzDST = 0; | ||||
|     // Account for DST where needed
 | ||||
|     gmTime = localtime(&sysTime); | ||||
|     if(gmTime->tm_isdst == 1) | ||||
|         tzDST = 3600; | ||||
|     else | ||||
|         tzDST = 0; | ||||
| 
 | ||||
| 	// Lazy way to get local time in sec
 | ||||
| 	gmTime	= gmtime(&sysTime); | ||||
| 	tzDiff = sysTime - mktime(gmTime); | ||||
|     // Lazy way to get local time in sec
 | ||||
|     gmTime    = gmtime(&sysTime); | ||||
|     tzDiff = sysTime - mktime(gmTime); | ||||
| 
 | ||||
| 	return (u64)(sysTime + tzDiff + tzDST); | ||||
|     return (u64)(sysTime + tzDiff + tzDST); | ||||
| } | ||||
| 
 | ||||
| // Return the current time formatted as Minutes:Seconds:Milliseconds
 | ||||
| // in the form 00:00:000.
 | ||||
| std::string Timer::GetTimeFormatted() | ||||
| { | ||||
| 	time_t sysTime; | ||||
| 	struct tm * gmTime; | ||||
| 	char formattedTime[13]; | ||||
| 	char tmp[13]; | ||||
|     time_t sysTime; | ||||
|     struct tm * gmTime; | ||||
|     char formattedTime[13]; | ||||
|     char tmp[13]; | ||||
| 
 | ||||
| 	time(&sysTime); | ||||
| 	gmTime = localtime(&sysTime); | ||||
|     time(&sysTime); | ||||
|     gmTime = localtime(&sysTime); | ||||
| 
 | ||||
| 	strftime(tmp, 6, "%M:%S", gmTime); | ||||
|     strftime(tmp, 6, "%M:%S", gmTime); | ||||
| 
 | ||||
| 	// Now tack on the milliseconds
 | ||||
|     // Now tack on the milliseconds
 | ||||
| #ifdef _WIN32 | ||||
| 	struct timeb tp; | ||||
| 	(void)::ftime(&tp); | ||||
| 	sprintf(formattedTime, "%s:%03i", tmp, tp.millitm); | ||||
|     struct timeb tp; | ||||
|     (void)::ftime(&tp); | ||||
|     sprintf(formattedTime, "%s:%03i", tmp, tp.millitm); | ||||
| #else | ||||
| 	struct timeval t; | ||||
| 	(void)gettimeofday(&t, NULL); | ||||
| 	sprintf(formattedTime, "%s:%03d", tmp, (int)(t.tv_usec / 1000)); | ||||
|     struct timeval t; | ||||
|     (void)gettimeofday(&t, NULL); | ||||
|     sprintf(formattedTime, "%s:%03d", tmp, (int)(t.tv_usec / 1000)); | ||||
| #endif | ||||
| 
 | ||||
| 	return std::string(formattedTime); | ||||
|     return std::string(formattedTime); | ||||
| } | ||||
| 
 | ||||
| // Returns a timestamp with decimals for precise time comparisons
 | ||||
|  | @ -196,31 +196,31 @@ std::string Timer::GetTimeFormatted() | |||
| double Timer::GetDoubleTime() | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	struct timeb tp; | ||||
| 	(void)::ftime(&tp); | ||||
|     struct timeb tp; | ||||
|     (void)::ftime(&tp); | ||||
| #else | ||||
| 	struct timeval t; | ||||
| 	(void)gettimeofday(&t, NULL); | ||||
|     struct timeval t; | ||||
|     (void)gettimeofday(&t, NULL); | ||||
| #endif | ||||
| 	// Get continuous timestamp
 | ||||
| 	u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); | ||||
|     // Get continuous timestamp
 | ||||
|     u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); | ||||
| 
 | ||||
| 	// Remove a few years. We only really want enough seconds to make
 | ||||
| 	// sure that we are detecting actual actions, perhaps 60 seconds is
 | ||||
| 	// enough really, but I leave a year of seconds anyway, in case the
 | ||||
| 	// user's clock is incorrect or something like that.
 | ||||
| 	TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); | ||||
|     // Remove a few years. We only really want enough seconds to make
 | ||||
|     // sure that we are detecting actual actions, perhaps 60 seconds is
 | ||||
|     // enough really, but I leave a year of seconds anyway, in case the
 | ||||
|     // user's clock is incorrect or something like that.
 | ||||
|     TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); | ||||
| 
 | ||||
| 	// Make a smaller integer that fits in the double
 | ||||
| 	u32 Seconds = (u32)TmpSeconds; | ||||
|     // Make a smaller integer that fits in the double
 | ||||
|     u32 Seconds = (u32)TmpSeconds; | ||||
| #ifdef _WIN32 | ||||
| 	double ms = tp.millitm / 1000.0 / 1000.0; | ||||
|     double ms = tp.millitm / 1000.0 / 1000.0; | ||||
| #else | ||||
| 	double ms = t.tv_usec / 1000000.0; | ||||
|     double ms = t.tv_usec / 1000000.0; | ||||
| #endif | ||||
| 	double TmpTime = Seconds + ms; | ||||
|     double TmpTime = Seconds + ms; | ||||
| 
 | ||||
| 	return TmpTime; | ||||
|     return TmpTime; | ||||
| } | ||||
| 
 | ||||
| } // Namespace Common
 | ||||
|  |  | |||
|  | @ -13,32 +13,32 @@ namespace Common | |||
| class Timer | ||||
| { | ||||
| public: | ||||
| 	Timer(); | ||||
|     Timer(); | ||||
| 
 | ||||
| 	void Start(); | ||||
| 	void Stop(); | ||||
| 	void Update(); | ||||
|     void Start(); | ||||
|     void Stop(); | ||||
|     void Update(); | ||||
| 
 | ||||
| 	// The time difference is always returned in milliseconds, regardless of alternative internal representation
 | ||||
| 	u64 GetTimeDifference(); | ||||
| 	void AddTimeDifference(); | ||||
|     // The time difference is always returned in milliseconds, regardless of alternative internal representation
 | ||||
|     u64 GetTimeDifference(); | ||||
|     void AddTimeDifference(); | ||||
| 
 | ||||
| 	static void IncreaseResolution(); | ||||
| 	static void RestoreResolution(); | ||||
| 	static u64 GetTimeSinceJan1970(); | ||||
| 	static u64 GetLocalTimeSinceJan1970(); | ||||
| 	static double GetDoubleTime(); | ||||
|     static void IncreaseResolution(); | ||||
|     static void RestoreResolution(); | ||||
|     static u64 GetTimeSinceJan1970(); | ||||
|     static u64 GetLocalTimeSinceJan1970(); | ||||
|     static double GetDoubleTime(); | ||||
| 
 | ||||
| 	static std::string GetTimeFormatted(); | ||||
| 	std::string GetTimeElapsedFormatted() const; | ||||
| 	u64 GetTimeElapsed(); | ||||
|     static std::string GetTimeFormatted(); | ||||
|     std::string GetTimeElapsedFormatted() const; | ||||
|     u64 GetTimeElapsed(); | ||||
| 
 | ||||
| 	static u32 GetTimeMs(); | ||||
|     static u32 GetTimeMs(); | ||||
| 
 | ||||
| private: | ||||
| 	u64 m_LastTime; | ||||
| 	u64 m_StartTime; | ||||
| 	bool m_Running; | ||||
|     u64 m_LastTime; | ||||
|     u64 m_StartTime; | ||||
|     bool m_Running; | ||||
| }; | ||||
| 
 | ||||
| } // Namespace Common
 | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ | |||
| 
 | ||||
| // is start of UTF sequence
 | ||||
| inline bool isutf(char c) { | ||||
| 	return (c & 0xC0) != 0x80; | ||||
|     return (c & 0xC0) != 0x80; | ||||
| } | ||||
| 
 | ||||
| static const u32 offsetsFromUTF8[6] = { | ||||
|  | @ -47,7 +47,7 @@ static const u8 trailingBytesForUTF8[256] = { | |||
|   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||||
|   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||||
|   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, | ||||
| 		2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5, | ||||
|         2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5, | ||||
| }; | ||||
| 
 | ||||
| /* returns length of next utf-8 sequence */ | ||||
|  | @ -405,59 +405,59 @@ int u8_is_locale_utf8(const char *locale) | |||
| } | ||||
| 
 | ||||
| int UTF8StringNonASCIICount(const char *utf8string) { | ||||
| 	UTF8 utf(utf8string); | ||||
| 	int count = 0; | ||||
| 	while (!utf.end()) { | ||||
| 		int c = utf.next(); | ||||
| 		if (c > 127) | ||||
| 			++count; | ||||
| 	} | ||||
| 	return count; | ||||
|     UTF8 utf(utf8string); | ||||
|     int count = 0; | ||||
|     while (!utf.end()) { | ||||
|         int c = utf.next(); | ||||
|         if (c > 127) | ||||
|             ++count; | ||||
|     } | ||||
|     return count; | ||||
| } | ||||
| 
 | ||||
| bool UTF8StringHasNonASCII(const char *utf8string) { | ||||
| 	return UTF8StringNonASCIICount(utf8string) > 0; | ||||
|     return UTF8StringNonASCIICount(utf8string) > 0; | ||||
| } | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| 
 | ||||
| std::string ConvertWStringToUTF8(const wchar_t *wstr) { | ||||
| 	int len = (int)wcslen(wstr); | ||||
| 	int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, NULL, NULL); | ||||
| 	std::string s; | ||||
| 	s.resize(size); | ||||
| 	if (size > 0) { | ||||
| 		WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, NULL, NULL); | ||||
| 	} | ||||
| 	return s; | ||||
|     int len = (int)wcslen(wstr); | ||||
|     int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, NULL, NULL); | ||||
|     std::string s; | ||||
|     s.resize(size); | ||||
|     if (size > 0) { | ||||
|         WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, NULL, NULL); | ||||
|     } | ||||
|     return s; | ||||
| } | ||||
| 
 | ||||
| std::string ConvertWStringToUTF8(const std::wstring &wstr) { | ||||
| 	int len = (int)wstr.size(); | ||||
| 	int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL); | ||||
| 	std::string s; | ||||
| 	s.resize(size); | ||||
| 	if (size > 0) { | ||||
| 		WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, NULL, NULL); | ||||
| 	} | ||||
| 	return s; | ||||
|     int len = (int)wstr.size(); | ||||
|     int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL); | ||||
|     std::string s; | ||||
|     s.resize(size); | ||||
|     if (size > 0) { | ||||
|         WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, NULL, NULL); | ||||
|     } | ||||
|     return s; | ||||
| } | ||||
| 
 | ||||
| void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { | ||||
| 	int len = (int)source.size(); | ||||
| 	int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); | ||||
| 	MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size)); | ||||
|     int len = (int)source.size(); | ||||
|     int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); | ||||
|     MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size)); | ||||
| } | ||||
| 
 | ||||
| std::wstring ConvertUTF8ToWString(const std::string &source) { | ||||
| 	int len = (int)source.size(); | ||||
| 	int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); | ||||
| 	std::wstring str; | ||||
| 	str.resize(size); | ||||
| 	if (size > 0) { | ||||
| 		MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, &str[0], size); | ||||
| 	} | ||||
| 	return str; | ||||
|     int len = (int)source.size(); | ||||
|     int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); | ||||
|     std::wstring str; | ||||
|     str.resize(size); | ||||
|     if (size > 0) { | ||||
|         MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, &str[0], size); | ||||
|     } | ||||
|     return str; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | @ -25,29 +25,29 @@ int u8_strlen(const char *s); | |||
| 
 | ||||
| class UTF8 { | ||||
| public: | ||||
| 	static const u32 INVALID = (u32)-1; | ||||
| 	UTF8(const char *c) : c_(c), index_(0) {} | ||||
| 	bool end() const { return c_[index_] == 0; } | ||||
| 	u32 next() { | ||||
| 		return u8_nextchar(c_, &index_); | ||||
| 	} | ||||
| 	u32 peek() { | ||||
| 		int tempIndex = index_; | ||||
| 		return u8_nextchar(c_, &tempIndex); | ||||
| 	} | ||||
| 	int length() const { | ||||
| 		return u8_strlen(c_); | ||||
| 	} | ||||
| 	int byteIndex() const { | ||||
| 		return index_; | ||||
| 	} | ||||
| 	static int encode(char *dest, u32 ch) { | ||||
| 		return u8_wc_toutf8(dest, ch); | ||||
| 	} | ||||
|     static const u32 INVALID = (u32)-1; | ||||
|     UTF8(const char *c) : c_(c), index_(0) {} | ||||
|     bool end() const { return c_[index_] == 0; } | ||||
|     u32 next() { | ||||
|         return u8_nextchar(c_, &index_); | ||||
|     } | ||||
|     u32 peek() { | ||||
|         int tempIndex = index_; | ||||
|         return u8_nextchar(c_, &tempIndex); | ||||
|     } | ||||
|     int length() const { | ||||
|         return u8_strlen(c_); | ||||
|     } | ||||
|     int byteIndex() const { | ||||
|         return index_; | ||||
|     } | ||||
|     static int encode(char *dest, u32 ch) { | ||||
|         return u8_wc_toutf8(dest, ch); | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| 	const char *c_; | ||||
| 	int index_; | ||||
|     const char *c_; | ||||
|     int index_; | ||||
| }; | ||||
| 
 | ||||
| int UTF8StringNonASCIICount(const char *utf8string); | ||||
|  |  | |||
|  | @ -6,22 +6,22 @@ | |||
| #include "scm_rev.h" | ||||
| 
 | ||||
| #ifdef _DEBUG | ||||
| 	#define BUILD_TYPE_STR "Debug " | ||||
|     #define BUILD_TYPE_STR "Debug " | ||||
| #elif defined DEBUGFAST | ||||
| 	#define BUILD_TYPE_STR "DebugFast " | ||||
|     #define BUILD_TYPE_STR "DebugFast " | ||||
| #else | ||||
| 	#define BUILD_TYPE_STR "" | ||||
|     #define BUILD_TYPE_STR "" | ||||
| #endif | ||||
| 
 | ||||
| const char *scm_rev_str = "emu " | ||||
| #if !SCM_IS_MASTER | ||||
| 	"[" SCM_BRANCH_STR "] " | ||||
|     "[" SCM_BRANCH_STR "] " | ||||
| #endif | ||||
| 
 | ||||
| #ifdef __INTEL_COMPILER | ||||
| 	BUILD_TYPE_STR SCM_DESC_STR "-ICC"; | ||||
|     BUILD_TYPE_STR SCM_DESC_STR "-ICC"; | ||||
| #else | ||||
| 	BUILD_TYPE_STR SCM_DESC_STR; | ||||
|     BUILD_TYPE_STR SCM_DESC_STR; | ||||
| #endif | ||||
| 
 | ||||
| #ifdef _M_X64 | ||||
|  | @ -29,7 +29,7 @@ const char *scm_rev_str = "emu " | |||
| #else | ||||
| #ifdef _M_ARM | ||||
| #define NP_ARCH "ARM" | ||||
| #else	 | ||||
| #else     | ||||
| #define NP_ARCH "x86" | ||||
| #endif | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue