mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40: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 | set(SRCS    src/break_points.cpp | ||||||
| 			src/console_listener.cpp |             src/console_listener.cpp | ||||||
| 			src/extended_trace.cpp |             src/extended_trace.cpp | ||||||
| 			src/file_search.cpp |             src/file_search.cpp | ||||||
| 			src/file_util.cpp |             src/file_util.cpp | ||||||
| 			src/hash.cpp |             src/hash.cpp | ||||||
| 			src/log_manager.cpp |             src/log_manager.cpp | ||||||
| 			src/math_util.cpp |             src/math_util.cpp | ||||||
| 			src/mem_arena.cpp |             src/mem_arena.cpp | ||||||
| 			src/memory_util.cpp |             src/memory_util.cpp | ||||||
| 			src/misc.cpp |             src/misc.cpp | ||||||
| 			src/msg_handler.cpp |             src/msg_handler.cpp | ||||||
| 			src/string_util.cpp |             src/string_util.cpp | ||||||
| 			src/thread.cpp |             src/thread.cpp | ||||||
| 			src/timer.cpp |             src/timer.cpp | ||||||
| 			src/version.cpp) |             src/version.cpp) | ||||||
| 
 | 
 | ||||||
| add_library(common STATIC ${SRCS}) | add_library(common STATIC ${SRCS}) | ||||||
|  |  | ||||||
|  | @ -25,42 +25,42 @@ namespace Common | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| inline void AtomicAdd(volatile u32& target, u32 value) { | 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) { | 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) { | inline void AtomicDecrement(volatile u32& target) { | ||||||
| 	__sync_add_and_fetch(&target, -1); |     __sync_add_and_fetch(&target, -1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline void AtomicIncrement(volatile u32& target) { | inline void AtomicIncrement(volatile u32& target) { | ||||||
| 	__sync_add_and_fetch(&target, 1); |     __sync_add_and_fetch(&target, 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline u32 AtomicLoad(volatile u32& src) { | 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) { | inline u32 AtomicLoadAcquire(volatile u32& src) { | ||||||
| 	//keep the compiler from caching any memory references
 |     //keep the compiler from caching any memory references
 | ||||||
| 	u32 result = src; // 32-bit reads are always atomic.
 |     u32 result = src; // 32-bit reads are always atomic.
 | ||||||
| 	//__sync_synchronize(); // TODO: May not be necessary.
 |     //__sync_synchronize(); // TODO: May not be necessary.
 | ||||||
| 	// Compiler instruction only. x86 loads always have acquire semantics.
 |     // Compiler instruction only. x86 loads always have acquire semantics.
 | ||||||
| 	__asm__ __volatile__ ( "":::"memory" ); |     __asm__ __volatile__ ( "":::"memory" ); | ||||||
| 	return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline void AtomicOr(volatile u32& target, u32 value) { | 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) { | 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) { | 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) { | 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) { | 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) { | inline void AtomicIncrement(volatile u32& target) { | ||||||
| 	InterlockedIncrement((volatile LONG*)&target); |     InterlockedIncrement((volatile LONG*)&target); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline void AtomicDecrement(volatile u32& target) { | inline void AtomicDecrement(volatile u32& target) { | ||||||
| 	InterlockedDecrement((volatile LONG*)&target); |     InterlockedDecrement((volatile LONG*)&target); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline u32 AtomicLoad(volatile u32& src) { | 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) { | inline u32 AtomicLoadAcquire(volatile u32& src) { | ||||||
| 	u32 result = src; // 32-bit reads are always atomic.
 |     u32 result = src; // 32-bit reads are always atomic.
 | ||||||
| 	_ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics.
 |     _ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics.
 | ||||||
| 	return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline void AtomicOr(volatile u32& target, u32 value) { | 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) { | 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) { | inline void AtomicStoreRelease(volatile u32& dest, u32 value) { | ||||||
| 	_WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics.
 |     _WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics.
 | ||||||
| 	dest = value; // 32-bit writes are always atomic.
 |     dest = value; // 32-bit writes are always atomic.
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -11,193 +11,193 @@ | ||||||
| 
 | 
 | ||||||
| bool BreakPoints::IsAddressBreakPoint(u32 _iAddress) | bool BreakPoints::IsAddressBreakPoint(u32 _iAddress) | ||||||
| { | { | ||||||
| 	for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) |     for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | ||||||
| 		if (i->iAddress == _iAddress) |         if (i->iAddress == _iAddress) | ||||||
| 			return true; |             return true; | ||||||
| 	return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool BreakPoints::IsTempBreakPoint(u32 _iAddress) | bool BreakPoints::IsTempBreakPoint(u32 _iAddress) | ||||||
| { | { | ||||||
| 	for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) |     for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | ||||||
| 		if (i->iAddress == _iAddress && i->bTemporary) |         if (i->iAddress == _iAddress && i->bTemporary) | ||||||
| 			return true; |             return true; | ||||||
| 	return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const | BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const | ||||||
| { | { | ||||||
| 	TBreakPointsStr bps; |     TBreakPointsStr bps; | ||||||
| 	for (TBreakPoints::const_iterator i = m_BreakPoints.begin(); |     for (TBreakPoints::const_iterator i = m_BreakPoints.begin(); | ||||||
| 		i != m_BreakPoints.end(); ++i) |         i != m_BreakPoints.end(); ++i) | ||||||
| 	{ |     { | ||||||
| 		if (!i->bTemporary) |         if (!i->bTemporary) | ||||||
| 		{ |         { | ||||||
| 			std::stringstream bp; |             std::stringstream bp; | ||||||
| 			bp << std::hex << i->iAddress << " " << (i->bOn ? "n" : ""); |             bp << std::hex << i->iAddress << " " << (i->bOn ? "n" : ""); | ||||||
| 			bps.push_back(bp.str()); |             bps.push_back(bp.str()); | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	return bps; |     return bps; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) | void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) | ||||||
| { | { | ||||||
| 	for (TBreakPointsStr::const_iterator i = bps.begin(); i != bps.end(); ++i) |     for (TBreakPointsStr::const_iterator i = bps.begin(); i != bps.end(); ++i) | ||||||
| 	{ |     { | ||||||
| 		TBreakPoint bp; |         TBreakPoint bp; | ||||||
| 		std::stringstream bpstr; |         std::stringstream bpstr; | ||||||
| 		bpstr << std::hex << *i; |         bpstr << std::hex << *i; | ||||||
| 		bpstr >> bp.iAddress; |         bpstr >> bp.iAddress; | ||||||
| 		bp.bOn = i->find("n") != i->npos; |         bp.bOn = i->find("n") != i->npos; | ||||||
| 		bp.bTemporary = false; |         bp.bTemporary = false; | ||||||
| 		Add(bp); |         Add(bp); | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BreakPoints::Add(const TBreakPoint& bp) | void BreakPoints::Add(const TBreakPoint& bp) | ||||||
| { | { | ||||||
| 	if (!IsAddressBreakPoint(bp.iAddress)) |     if (!IsAddressBreakPoint(bp.iAddress)) | ||||||
| 	{ |     { | ||||||
| 		m_BreakPoints.push_back(bp); |         m_BreakPoints.push_back(bp); | ||||||
| 		//if (jit)
 |         //if (jit)
 | ||||||
| 		//	jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 |         //    jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BreakPoints::Add(u32 em_address, bool temp) | void BreakPoints::Add(u32 em_address, bool temp) | ||||||
| { | { | ||||||
| 	if (!IsAddressBreakPoint(em_address)) // only add new addresses
 |     if (!IsAddressBreakPoint(em_address)) // only add new addresses
 | ||||||
| 	{ |     { | ||||||
| 		TBreakPoint pt; // breakpoint settings
 |         TBreakPoint pt; // breakpoint settings
 | ||||||
| 		pt.bOn = true; |         pt.bOn = true; | ||||||
| 		pt.bTemporary = temp; |         pt.bTemporary = temp; | ||||||
| 		pt.iAddress = em_address; |         pt.iAddress = em_address; | ||||||
| 
 | 
 | ||||||
| 		m_BreakPoints.push_back(pt); |         m_BreakPoints.push_back(pt); | ||||||
| 
 | 
 | ||||||
| 		//if (jit)
 |         //if (jit)
 | ||||||
| 		//	jit->GetBlockCache()->InvalidateICache(em_address, 4);
 |         //    jit->GetBlockCache()->InvalidateICache(em_address, 4);
 | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BreakPoints::Remove(u32 em_address) | void BreakPoints::Remove(u32 em_address) | ||||||
| { | { | ||||||
| 	for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) |     for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | ||||||
| 	{ |     { | ||||||
| 		if (i->iAddress == em_address) |         if (i->iAddress == em_address) | ||||||
| 		{ |         { | ||||||
| 			m_BreakPoints.erase(i); |             m_BreakPoints.erase(i); | ||||||
| 			//if (jit)
 |             //if (jit)
 | ||||||
| 			//	jit->GetBlockCache()->InvalidateICache(em_address, 4);
 |             //    jit->GetBlockCache()->InvalidateICache(em_address, 4);
 | ||||||
| 			return; |             return; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BreakPoints::Clear() | void BreakPoints::Clear() | ||||||
| { | { | ||||||
| 	//if (jit)
 |     //if (jit)
 | ||||||
| 	//{
 |     //{
 | ||||||
| 	//	std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(),
 |     //    std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(),
 | ||||||
| 	//		[](const TBreakPoint& bp)
 |     //        [](const TBreakPoint& bp)
 | ||||||
| 	//		{
 |     //        {
 | ||||||
| 	//			jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 |     //            jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 | ||||||
| 	//		}
 |     //        }
 | ||||||
| 	//	);
 |     //    );
 | ||||||
| 	//}
 |     //}
 | ||||||
|      |      | ||||||
| 	m_BreakPoints.clear(); |     m_BreakPoints.clear(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MemChecks::TMemChecksStr MemChecks::GetStrings() const | MemChecks::TMemChecksStr MemChecks::GetStrings() const | ||||||
| { | { | ||||||
| 	TMemChecksStr mcs; |     TMemChecksStr mcs; | ||||||
| 	for (TMemChecks::const_iterator i = m_MemChecks.begin(); |     for (TMemChecks::const_iterator i = m_MemChecks.begin(); | ||||||
| 		i != m_MemChecks.end(); ++i) |         i != m_MemChecks.end(); ++i) | ||||||
| 	{ |     { | ||||||
| 		std::stringstream mc; |         std::stringstream mc; | ||||||
| 		mc << std::hex << i->StartAddress; |         mc << std::hex << i->StartAddress; | ||||||
| 		mc << " " << (i->bRange ? i->EndAddress : i->StartAddress) << " " << |         mc << " " << (i->bRange ? i->EndAddress : i->StartAddress) << " " << | ||||||
| 			(i->bRange ? "n" : "") << (i->OnRead ? "r" : "") << |             (i->bRange ? "n" : "") << (i->OnRead ? "r" : "") << | ||||||
| 			(i->OnWrite ? "w" : "") << (i->Log ? "l" : "") << (i->Break ? "p" : ""); |             (i->OnWrite ? "w" : "") << (i->Log ? "l" : "") << (i->Break ? "p" : ""); | ||||||
| 		mcs.push_back(mc.str()); |         mcs.push_back(mc.str()); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	return mcs; |     return mcs; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MemChecks::AddFromStrings(const TMemChecksStr& mcs) | void MemChecks::AddFromStrings(const TMemChecksStr& mcs) | ||||||
| { | { | ||||||
| 	for (TMemChecksStr::const_iterator i = mcs.begin(); i != mcs.end(); ++i) |     for (TMemChecksStr::const_iterator i = mcs.begin(); i != mcs.end(); ++i) | ||||||
| 	{ |     { | ||||||
| 		TMemCheck mc; |         TMemCheck mc; | ||||||
| 		std::stringstream mcstr; |         std::stringstream mcstr; | ||||||
| 		mcstr << std::hex << *i; |         mcstr << std::hex << *i; | ||||||
| 		mcstr >> mc.StartAddress; |         mcstr >> mc.StartAddress; | ||||||
| 		mc.bRange	= i->find("n") != i->npos; |         mc.bRange    = i->find("n") != i->npos; | ||||||
| 		mc.OnRead	= i->find("r") != i->npos; |         mc.OnRead    = i->find("r") != i->npos; | ||||||
| 		mc.OnWrite	= i->find("w") != i->npos; |         mc.OnWrite    = i->find("w") != i->npos; | ||||||
| 		mc.Log		= i->find("l") != i->npos; |         mc.Log        = i->find("l") != i->npos; | ||||||
| 		mc.Break	= i->find("p") != i->npos; |         mc.Break    = i->find("p") != i->npos; | ||||||
| 		if (mc.bRange) |         if (mc.bRange) | ||||||
| 			mcstr >> mc.EndAddress; |             mcstr >> mc.EndAddress; | ||||||
| 		else |         else | ||||||
| 			mc.EndAddress = mc.StartAddress; |             mc.EndAddress = mc.StartAddress; | ||||||
| 		Add(mc); |         Add(mc); | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MemChecks::Add(const TMemCheck& _rMemoryCheck) | void MemChecks::Add(const TMemCheck& _rMemoryCheck) | ||||||
| { | { | ||||||
| 	if (GetMemCheck(_rMemoryCheck.StartAddress) == 0) |     if (GetMemCheck(_rMemoryCheck.StartAddress) == 0) | ||||||
| 		m_MemChecks.push_back(_rMemoryCheck); |         m_MemChecks.push_back(_rMemoryCheck); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MemChecks::Remove(u32 _Address) | void MemChecks::Remove(u32 _Address) | ||||||
| { | { | ||||||
| 	for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) |     for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) | ||||||
| 	{ |     { | ||||||
| 		if (i->StartAddress == _Address) |         if (i->StartAddress == _Address) | ||||||
| 		{ |         { | ||||||
| 			m_MemChecks.erase(i); |             m_MemChecks.erase(i); | ||||||
| 			return; |             return; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| TMemCheck *MemChecks::GetMemCheck(u32 address) | TMemCheck *MemChecks::GetMemCheck(u32 address) | ||||||
| { | { | ||||||
| 	for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) |     for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) | ||||||
| 	{ |     { | ||||||
| 		if (i->bRange) |         if (i->bRange) | ||||||
| 		{ |         { | ||||||
| 			if (address >= i->StartAddress && address <= i->EndAddress) |             if (address >= i->StartAddress && address <= i->EndAddress) | ||||||
| 				return &(*i); |                 return &(*i); | ||||||
| 		} |         } | ||||||
| 		else if (i->StartAddress == address) |         else if (i->StartAddress == address) | ||||||
| 			return &(*i); |             return &(*i); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// none found
 |     // none found
 | ||||||
| 	return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void TMemCheck::Action(DebugInterface *debug_interface, u32 iValue, u32 addr, | 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 ((write && OnWrite) || (!write && OnRead)) | ||||||
| 	{ |     { | ||||||
| 		if (Log) |         if (Log) | ||||||
| 		{ |         { | ||||||
| 			INFO_LOG(MEMMAP, "CHK %08x (%s) %s%i %0*x at %08x (%s)", |             INFO_LOG(MEMMAP, "CHK %08x (%s) %s%i %0*x at %08x (%s)", | ||||||
| 				pc, debug_interface->getDescription(pc).c_str(), |                 pc, debug_interface->getDescription(pc).c_str(), | ||||||
| 				write ? "Write" : "Read", size*8, size*2, iValue, addr, |                 write ? "Write" : "Read", size*8, size*2, iValue, addr, | ||||||
| 				debug_interface->getDescription(addr).c_str() |                 debug_interface->getDescription(addr).c_str() | ||||||
| 				); |                 ); | ||||||
| 		} |         } | ||||||
| 		if (Break) |         if (Break) | ||||||
| 			debug_interface->breakNow(); |             debug_interface->breakNow(); | ||||||
| 	} |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -14,64 +14,64 @@ class DebugInterface; | ||||||
| 
 | 
 | ||||||
| struct TBreakPoint | struct TBreakPoint | ||||||
| { | { | ||||||
| 	u32		iAddress; |     u32        iAddress; | ||||||
| 	bool	bOn; |     bool    bOn; | ||||||
| 	bool	bTemporary; |     bool    bTemporary; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct TMemCheck | struct TMemCheck | ||||||
| { | { | ||||||
| 	TMemCheck() { |     TMemCheck() { | ||||||
| 		numHits = 0; |         numHits = 0; | ||||||
| 		StartAddress = EndAddress = 0; |         StartAddress = EndAddress = 0; | ||||||
| 		bRange = OnRead = OnWrite = Log = Break = false; |         bRange = OnRead = OnWrite = Log = Break = false; | ||||||
| 	} |     } | ||||||
| 	u32 StartAddress; |     u32 StartAddress; | ||||||
| 	u32 EndAddress; |     u32 EndAddress; | ||||||
| 
 | 
 | ||||||
| 	bool	bRange; |     bool    bRange; | ||||||
| 
 | 
 | ||||||
| 	bool	OnRead; |     bool    OnRead; | ||||||
| 	bool	OnWrite; |     bool    OnWrite; | ||||||
| 
 | 
 | ||||||
| 	bool	Log; |     bool    Log; | ||||||
| 	bool	Break; |     bool    Break; | ||||||
| 
 | 
 | ||||||
| 	u32		numHits; |     u32        numHits; | ||||||
| 
 | 
 | ||||||
| 	void Action(DebugInterface *dbg_interface, u32 _iValue, u32 addr, |     void Action(DebugInterface *dbg_interface, u32 _iValue, u32 addr, | ||||||
| 				bool write, int size, u32 pc); |                 bool write, int size, u32 pc); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Code breakpoints.
 | // Code breakpoints.
 | ||||||
| class BreakPoints | class BreakPoints | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	typedef std::vector<TBreakPoint> TBreakPoints; |     typedef std::vector<TBreakPoint> TBreakPoints; | ||||||
| 	typedef std::vector<std::string> TBreakPointsStr; |     typedef std::vector<std::string> TBreakPointsStr; | ||||||
| 
 | 
 | ||||||
| 	const TBreakPoints& GetBreakPoints() { return m_BreakPoints; } |     const TBreakPoints& GetBreakPoints() { return m_BreakPoints; } | ||||||
| 
 | 
 | ||||||
| 	TBreakPointsStr GetStrings() const; |     TBreakPointsStr GetStrings() const; | ||||||
| 	void AddFromStrings(const TBreakPointsStr& bps); |     void AddFromStrings(const TBreakPointsStr& bps); | ||||||
| 
 | 
 | ||||||
| 	// is address breakpoint
 |     // is address breakpoint
 | ||||||
| 	bool IsAddressBreakPoint(u32 _iAddress); |     bool IsAddressBreakPoint(u32 _iAddress); | ||||||
| 	bool IsTempBreakPoint(u32 _iAddress); |     bool IsTempBreakPoint(u32 _iAddress); | ||||||
| 
 | 
 | ||||||
| 	// Add BreakPoint
 |     // Add BreakPoint
 | ||||||
| 	void Add(u32 em_address, bool temp=false); |     void Add(u32 em_address, bool temp=false); | ||||||
| 	void Add(const TBreakPoint& bp); |     void Add(const TBreakPoint& bp); | ||||||
| 
 | 
 | ||||||
| 	// Remove Breakpoint
 |     // Remove Breakpoint
 | ||||||
| 	void Remove(u32 _iAddress); |     void Remove(u32 _iAddress); | ||||||
| 	void Clear(); |     void Clear(); | ||||||
| 
 | 
 | ||||||
|     void DeleteByAddress(u32 _Address); |     void DeleteByAddress(u32 _Address); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	TBreakPoints m_BreakPoints; |     TBreakPoints m_BreakPoints; | ||||||
| 	u32	m_iBreakOnCount; |     u32    m_iBreakOnCount; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -79,23 +79,23 @@ private: | ||||||
| class MemChecks | class MemChecks | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	typedef std::vector<TMemCheck> TMemChecks; |     typedef std::vector<TMemCheck> TMemChecks; | ||||||
| 	typedef std::vector<std::string> TMemChecksStr; |     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; |     TMemChecksStr GetStrings() const; | ||||||
| 	void AddFromStrings(const TMemChecksStr& mcs); |     void AddFromStrings(const TMemChecksStr& mcs); | ||||||
| 
 | 
 | ||||||
| 	void Add(const TMemCheck& _rMemoryCheck); |     void Add(const TMemCheck& _rMemoryCheck); | ||||||
| 
 | 
 | ||||||
| 	// memory breakpoint
 |     // memory breakpoint
 | ||||||
| 	TMemCheck *GetMemCheck(u32 address); |     TMemCheck *GetMemCheck(u32 address); | ||||||
|     void Remove(u32 _Address); |     void Remove(u32 _Address); | ||||||
| 
 | 
 | ||||||
| 	void Clear() { m_MemChecks.clear(); }; |     void Clear() { m_MemChecks.clear(); }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -34,12 +34,12 @@ extern const char *netplay_dolphin_ver; | ||||||
| class NonCopyable | class NonCopyable | ||||||
| { | { | ||||||
| protected: | protected: | ||||||
| 	NonCopyable() {} |     NonCopyable() {} | ||||||
| 	NonCopyable(const NonCopyable&&) {} |     NonCopyable(const NonCopyable&&) {} | ||||||
| 	void operator=(const NonCopyable&&) {} |     void operator=(const NonCopyable&&) {} | ||||||
| private: | private: | ||||||
| 	NonCopyable(NonCopyable&); |     NonCopyable(NonCopyable&); | ||||||
| 	NonCopyable& operator=(NonCopyable& other); |     NonCopyable& operator=(NonCopyable& other); | ||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | @ -61,40 +61,40 @@ private: | ||||||
| #elif defined _WIN32 | #elif defined _WIN32 | ||||||
| 
 | 
 | ||||||
| // Check MSC ver
 | // Check MSC ver
 | ||||||
| 	#if !defined _MSC_VER || _MSC_VER <= 1000 |     #if !defined _MSC_VER || _MSC_VER <= 1000 | ||||||
| 		#error needs at least version 1000 of MSC |         #error needs at least version 1000 of MSC | ||||||
| 	#endif |     #endif | ||||||
| 
 | 
 | ||||||
| 	#define NOMINMAX |     #define NOMINMAX | ||||||
| 
 | 
 | ||||||
| // Memory leak checks
 | // Memory leak checks
 | ||||||
| 	#define CHECK_HEAP_INTEGRITY() |     #define CHECK_HEAP_INTEGRITY() | ||||||
| 
 | 
 | ||||||
| // Alignment
 | // Alignment
 | ||||||
| 	#define MEMORY_ALIGNED16(x) __declspec(align(16)) x |     #define MEMORY_ALIGNED16(x) __declspec(align(16)) x | ||||||
| 	#define MEMORY_ALIGNED32(x) __declspec(align(32)) x |     #define MEMORY_ALIGNED32(x) __declspec(align(32)) x | ||||||
| 	#define MEMORY_ALIGNED64(x) __declspec(align(64)) x |     #define MEMORY_ALIGNED64(x) __declspec(align(64)) x | ||||||
| 	#define MEMORY_ALIGNED128(x) __declspec(align(128)) x |     #define MEMORY_ALIGNED128(x) __declspec(align(128)) x | ||||||
| 	#define MEMORY_ALIGNED16_DECL(x) __declspec(align(16)) x |     #define MEMORY_ALIGNED16_DECL(x) __declspec(align(16)) x | ||||||
| 	#define MEMORY_ALIGNED64_DECL(x) __declspec(align(64)) x |     #define MEMORY_ALIGNED64_DECL(x) __declspec(align(64)) x | ||||||
| 
 | 
 | ||||||
| // Since they are always around on windows
 | // Since they are always around on windows
 | ||||||
| 	#define HAVE_WX 1 |     #define HAVE_WX 1 | ||||||
| 	#define HAVE_OPENAL 1 |     #define HAVE_OPENAL 1 | ||||||
| 
 | 
 | ||||||
| 	#define HAVE_PORTAUDIO 1 |     #define HAVE_PORTAUDIO 1 | ||||||
| 
 | 
 | ||||||
| // Debug definitions
 | // Debug definitions
 | ||||||
| 	#if defined(_DEBUG) |     #if defined(_DEBUG) | ||||||
| 		#include <crtdbg.h> |         #include <crtdbg.h> | ||||||
| 		#undef CHECK_HEAP_INTEGRITY |         #undef CHECK_HEAP_INTEGRITY | ||||||
| 		#define CHECK_HEAP_INTEGRITY() {if (!_CrtCheckMemory()) PanicAlert("memory corruption detected. see log.");} |         #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:
 |         // If you want to see how much a pain in the ass singletons are, for example:
 | ||||||
| 		// {614} normal block at 0x030C5310, 188 bytes long.
 |         // {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
 |         // 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); } }; |         struct CrtDebugBreak { CrtDebugBreak(int spot) { _CrtSetBreakAlloc(spot); } }; | ||||||
| 		//CrtDebugBreak breakAt(614);
 |         //CrtDebugBreak breakAt(614);
 | ||||||
| 	#endif // end DEBUG/FAST
 |     #endif // end DEBUG/FAST
 | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | @ -149,18 +149,18 @@ private: | ||||||
| // Host communication.
 | // Host communication.
 | ||||||
| enum HOST_COMM | enum HOST_COMM | ||||||
| { | { | ||||||
| 	// Begin at 10 in case there is already messages with wParam = 0, 1, 2 and so on
 |     // Begin at 10 in case there is already messages with wParam = 0, 1, 2 and so on
 | ||||||
| 	WM_USER_STOP = 10, |     WM_USER_STOP = 10, | ||||||
| 	WM_USER_CREATE, |     WM_USER_CREATE, | ||||||
| 	WM_USER_SETCURSOR, |     WM_USER_SETCURSOR, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Used for notification on emulation state
 | // Used for notification on emulation state
 | ||||||
| enum EMUSTATE_CHANGE | enum EMUSTATE_CHANGE | ||||||
| { | { | ||||||
| 	EMUSTATE_CHANGE_PLAY = 1, |     EMUSTATE_CHANGE_PLAY = 1, | ||||||
| 	EMUSTATE_CHANGE_PAUSE, |     EMUSTATE_CHANGE_PAUSE, | ||||||
| 	EMUSTATE_CHANGE_STOP |     EMUSTATE_CHANGE_STOP | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // _COMMON_H_
 | #endif // _COMMON_H_
 | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ template<> struct CompileTimeAssert<true> {}; | ||||||
| #define b8(x)   ( b4(x) | ( b4(x) >> 4) ) | #define b8(x)   ( b4(x) | ( b4(x) >> 4) ) | ||||||
| #define b16(x)  ( b8(x) | ( b8(x) >> 8) )   | #define b16(x)  ( b8(x) | ( b8(x) >> 8) )   | ||||||
| #define b32(x)  (b16(x) | (b16(x) >>16) ) | #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])) | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) | ||||||
| 
 | 
 | ||||||
|  | @ -29,11 +29,11 @@ template<> struct CompileTimeAssert<true> {}; | ||||||
| static __inline __m128i __attribute__((__always_inline__)) | static __inline __m128i __attribute__((__always_inline__)) | ||||||
| _mm_shuffle_epi8(__m128i a, __m128i mask) | _mm_shuffle_epi8(__m128i a, __m128i mask) | ||||||
| { | { | ||||||
| 	__m128i result; |     __m128i result; | ||||||
| 	__asm__("pshufb %1, %0" |     __asm__("pshufb %1, %0" | ||||||
| 		: "=x" (result) |         : "=x" (result) | ||||||
| 		: "xm" (mask), "0" (a)); |         : "xm" (mask), "0" (a)); | ||||||
| 	return result; |     return result; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | @ -47,103 +47,103 @@ _mm_shuffle_epi8(__m128i a, __m128i mask) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| // go to debugger mode
 | // go to debugger mode
 | ||||||
| 	#ifdef GEKKO |     #ifdef GEKKO | ||||||
| 		#define Crash() |         #define Crash() | ||||||
| 	#elif defined _M_GENERIC |     #elif defined _M_GENERIC | ||||||
| 		#define Crash() { exit(1); } |         #define Crash() { exit(1); } | ||||||
| 	#else |     #else | ||||||
| 		#define Crash() {asm ("int $3");} |         #define Crash() {asm ("int $3");} | ||||||
| 	#endif |     #endif | ||||||
| 	#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) |     #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) | ||||||
| // GCC 4.8 defines all the rotate functions now
 | // 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
 | // Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit
 | ||||||
| #ifndef _rotl | #ifndef _rotl | ||||||
| inline u32 _rotl(u32 x, int shift) { | inline u32 _rotl(u32 x, int shift) { | ||||||
| 	shift &= 31; |     shift &= 31; | ||||||
| 	if (!shift) return x; |     if (!shift) return x; | ||||||
| 	return (x << shift) | (x >> (32 - shift)); |     return (x << shift) | (x >> (32 - shift)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline u32 _rotr(u32 x, int shift) { | inline u32 _rotr(u32 x, int shift) { | ||||||
| 	shift &= 31; |     shift &= 31; | ||||||
| 	if (!shift) return x; |     if (!shift) return x; | ||||||
| 	return (x >> shift) | (x << (32 - shift)); |     return (x >> shift) | (x << (32 - shift)); | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| inline u64 _rotl64(u64 x, unsigned int shift){ | inline u64 _rotl64(u64 x, unsigned int shift){ | ||||||
| 	unsigned int n = shift % 64; |     unsigned int n = shift % 64; | ||||||
| 	return (x << n) | (x >> (64 - n)); |     return (x << n) | (x >> (64 - n)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline u64 _rotr64(u64 x, unsigned int shift){ | inline u64 _rotr64(u64 x, unsigned int shift){ | ||||||
| 	unsigned int n = shift % 64; |     unsigned int n = shift % 64; | ||||||
| 	return (x >> n) | (x << (64 - n)); |     return (x >> n) | (x << (64 - n)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #else // WIN32
 | #else // WIN32
 | ||||||
| // Function Cross-Compatibility
 | // Function Cross-Compatibility
 | ||||||
| 	#define strcasecmp _stricmp |     #define strcasecmp _stricmp | ||||||
| 	#define strncasecmp _strnicmp |     #define strncasecmp _strnicmp | ||||||
| 	#define unlink _unlink |     #define unlink _unlink | ||||||
| 	#define snprintf _snprintf |     #define snprintf _snprintf | ||||||
| 	#define vscprintf _vscprintf |     #define vscprintf _vscprintf | ||||||
|      |      | ||||||
| // Locale Cross-Compatibility
 | // Locale Cross-Compatibility
 | ||||||
| 	#define locale_t _locale_t |     #define locale_t _locale_t | ||||||
| 	#define freelocale _free_locale |     #define freelocale _free_locale | ||||||
| 	#define newlocale(mask, locale, base) _create_locale(mask, locale) |     #define newlocale(mask, locale, base) _create_locale(mask, locale) | ||||||
|      |      | ||||||
| 	#define LC_GLOBAL_LOCALE	((locale_t)-1) |     #define LC_GLOBAL_LOCALE    ((locale_t)-1) | ||||||
| 	#define LC_ALL_MASK			LC_ALL |     #define LC_ALL_MASK            LC_ALL | ||||||
| 	#define LC_COLLATE_MASK		LC_COLLATE |     #define LC_COLLATE_MASK        LC_COLLATE | ||||||
| 	#define LC_CTYPE_MASK		LC_CTYPE |     #define LC_CTYPE_MASK        LC_CTYPE | ||||||
| 	#define LC_MONETARY_MASK	LC_MONETARY |     #define LC_MONETARY_MASK    LC_MONETARY | ||||||
| 	#define LC_NUMERIC_MASK		LC_NUMERIC |     #define LC_NUMERIC_MASK        LC_NUMERIC | ||||||
| 	#define LC_TIME_MASK		LC_TIME |     #define LC_TIME_MASK        LC_TIME | ||||||
|      |      | ||||||
| 	inline locale_t uselocale(locale_t new_locale) |     inline locale_t uselocale(locale_t new_locale) | ||||||
| 	{ |     { | ||||||
| 		// Retrieve the current per thread locale setting
 |         // Retrieve the current per thread locale setting
 | ||||||
| 		bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE); |         bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE); | ||||||
| 
 | 
 | ||||||
| 		// Retrieve the current thread-specific locale
 |         // Retrieve the current thread-specific locale
 | ||||||
| 		locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE; |         locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE; | ||||||
| 
 | 
 | ||||||
| 		if(new_locale == LC_GLOBAL_LOCALE) |         if(new_locale == LC_GLOBAL_LOCALE) | ||||||
| 		{ |         { | ||||||
| 			// Restore the global locale
 |             // Restore the global locale
 | ||||||
| 			_configthreadlocale(_DISABLE_PER_THREAD_LOCALE); |             _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); | ||||||
| 		} |         } | ||||||
| 		else if(new_locale != NULL) |         else if(new_locale != NULL) | ||||||
| 		{ |         { | ||||||
| 			// Configure the thread to set the locale only for this thread
 |             // Configure the thread to set the locale only for this thread
 | ||||||
| 			_configthreadlocale(_ENABLE_PER_THREAD_LOCALE); |             _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); | ||||||
| 
 | 
 | ||||||
| 			// Set all locale categories
 |             // Set all locale categories
 | ||||||
| 			for(int i = LC_MIN; i <= LC_MAX; i++) |             for(int i = LC_MIN; i <= LC_MAX; i++) | ||||||
| 				setlocale(i, new_locale->locinfo->lc_category[i].locale); |                 setlocale(i, new_locale->locinfo->lc_category[i].locale); | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		return old_locale; |         return old_locale; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| // 64 bit offsets for windows
 | // 64 bit offsets for windows
 | ||||||
| 	#define fseeko _fseeki64 |     #define fseeko _fseeki64 | ||||||
| 	#define ftello _ftelli64 |     #define ftello _ftelli64 | ||||||
| 	#define atoll _atoi64 |     #define atoll _atoi64 | ||||||
| 	#define stat64 _stat64 |     #define stat64 _stat64 | ||||||
| 	#define fstat64 _fstat64 |     #define fstat64 _fstat64 | ||||||
| 	#define fileno _fileno |     #define fileno _fileno | ||||||
| 
 | 
 | ||||||
| 	#if _M_IX86 |     #if _M_IX86 | ||||||
| 		#define Crash() {__asm int 3} |         #define Crash() {__asm int 3} | ||||||
| 	#else |     #else | ||||||
| extern "C" { | extern "C" { | ||||||
| 	__declspec(dllimport) void __stdcall DebugBreak(void); |     __declspec(dllimport) void __stdcall DebugBreak(void); | ||||||
| } | } | ||||||
| 		#define Crash() {DebugBreak();} |         #define Crash() {DebugBreak();} | ||||||
| 	#endif // M_IX86
 |     #endif // M_IX86
 | ||||||
| #endif // WIN32 ndef
 | #endif // WIN32 ndef
 | ||||||
| 
 | 
 | ||||||
| // Dolphin's min and max functions
 | // 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);} | inline u64 swap64(u64 _data) {return bswap_64(_data);} | ||||||
| #elif __APPLE__ | #elif __APPLE__ | ||||||
| inline __attribute__((always_inline)) u16 swap16(u16 _data) | 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) | inline __attribute__((always_inline)) u32 swap32(u32 _data) | ||||||
| 	{return __builtin_bswap32(_data);} |     {return __builtin_bswap32(_data);} | ||||||
| inline __attribute__((always_inline)) u64 swap64(u64 _data) | inline __attribute__((always_inline)) u64 swap64(u64 _data) | ||||||
| 	{return __builtin_bswap64(_data);} |     {return __builtin_bswap64(_data);} | ||||||
| #elif __FreeBSD__ | #elif __FreeBSD__ | ||||||
| inline u16 swap16(u16 _data) {return bswap16(_data);} | inline u16 swap16(u16 _data) {return bswap16(_data);} | ||||||
| inline u32 swap32(u32 _data) {return bswap32(_data);} | inline u32 swap32(u32 _data) {return bswap32(_data);} | ||||||
|  | @ -216,28 +216,28 @@ inline void swap<1>(u8* data) | ||||||
| template <> | template <> | ||||||
| inline void swap<2>(u8* data) | inline void swap<2>(u8* data) | ||||||
| { | { | ||||||
| 	*reinterpret_cast<u16*>(data) = swap16(data); |     *reinterpret_cast<u16*>(data) = swap16(data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <> | template <> | ||||||
| inline void swap<4>(u8* data) | inline void swap<4>(u8* data) | ||||||
| { | { | ||||||
| 	*reinterpret_cast<u32*>(data) = swap32(data); |     *reinterpret_cast<u32*>(data) = swap32(data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <> | template <> | ||||||
| inline void swap<8>(u8* data) | inline void swap<8>(u8* data) | ||||||
| { | { | ||||||
| 	*reinterpret_cast<u64*>(data) = swap64(data); |     *reinterpret_cast<u64*>(data) = swap64(data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| inline T FromBigEndian(T data) | inline T FromBigEndian(T data) | ||||||
| { | { | ||||||
| 	//static_assert(std::is_arithmetic<T>::value, "function only makes sense with arithmetic types");
 |     //static_assert(std::is_arithmetic<T>::value, "function only makes sense with arithmetic types");
 | ||||||
|      |      | ||||||
| 	swap<sizeof(data)>(reinterpret_cast<u8*>(&data)); |     swap<sizeof(data)>(reinterpret_cast<u8*>(&data)); | ||||||
| 	return data; |     return data; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| }  // Namespace Common
 | }  // Namespace Common
 | ||||||
|  |  | ||||||
|  | @ -13,34 +13,34 @@ | ||||||
| #define DIR_SEP_CHR '/' | #define DIR_SEP_CHR '/' | ||||||
| 
 | 
 | ||||||
| #ifndef MAX_PATH | #ifndef MAX_PATH | ||||||
| #define MAX_PATH	260 | #define MAX_PATH    260 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| // The user data dir
 | // The user data dir
 | ||||||
| #define ROOT_DIR "." | #define ROOT_DIR "." | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	#define USERDATA_DIR "user" |     #define USERDATA_DIR "user" | ||||||
| 	#define EMU_DATA_DIR "emu" |     #define EMU_DATA_DIR "emu" | ||||||
| #else | #else | ||||||
| 	#define USERDATA_DIR "user" |     #define USERDATA_DIR "user" | ||||||
| 	#ifdef USER_DIR |     #ifdef USER_DIR | ||||||
| 		#define EMU_DATA_DIR USER_DIR |         #define EMU_DATA_DIR USER_DIR | ||||||
| 	#else |     #else | ||||||
| 		#define EMU_DATA_DIR ".emu" |         #define EMU_DATA_DIR ".emu" | ||||||
| 	#endif |     #endif | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| // Shared data dirs (Sys and shared User for linux)
 | // Shared data dirs (Sys and shared User for linux)
 | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	#define SYSDATA_DIR "sys" |     #define SYSDATA_DIR "sys" | ||||||
| #else | #else | ||||||
| 	#ifdef DATA_DIR |     #ifdef DATA_DIR | ||||||
| 		#define SYSDATA_DIR DATA_DIR "sys" |         #define SYSDATA_DIR DATA_DIR "sys" | ||||||
| 		#define SHARED_USER_DIR  DATA_DIR USERDATA_DIR DIR_SEP |         #define SHARED_USER_DIR  DATA_DIR USERDATA_DIR DIR_SEP | ||||||
| 	#else |     #else | ||||||
| 		#define SYSDATA_DIR "sys" |         #define SYSDATA_DIR "sys" | ||||||
| 		#define SHARED_USER_DIR  ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP |         #define SHARED_USER_DIR  ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP | ||||||
| 	#endif |     #endif | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| // Dirs in both User and Sys
 | // Dirs in both User and Sys
 | ||||||
|  | @ -49,31 +49,31 @@ | ||||||
| #define JAP_DIR "JAP" | #define JAP_DIR "JAP" | ||||||
| 
 | 
 | ||||||
| // Subdirs in the User dir returned by GetUserPath(D_USER_IDX)
 | // Subdirs in the User dir returned by GetUserPath(D_USER_IDX)
 | ||||||
| #define CONFIG_DIR			"config" | #define CONFIG_DIR            "config" | ||||||
| #define GAMECONFIG_DIR		"game_config" | #define GAMECONFIG_DIR        "game_config" | ||||||
| #define MAPS_DIR			"maps" | #define MAPS_DIR            "maps" | ||||||
| #define CACHE_DIR			"cache" | #define CACHE_DIR            "cache" | ||||||
| #define SHADERCACHE_DIR		"shader_cache" | #define SHADERCACHE_DIR        "shader_cache" | ||||||
| #define STATESAVES_DIR		"state_saves" | #define STATESAVES_DIR        "state_saves" | ||||||
| #define SCREENSHOTS_DIR		"screenShots" | #define SCREENSHOTS_DIR        "screenShots" | ||||||
| #define DUMP_DIR			"dump" | #define DUMP_DIR            "dump" | ||||||
| #define DUMP_TEXTURES_DIR	"textures" | #define DUMP_TEXTURES_DIR    "textures" | ||||||
| #define DUMP_FRAMES_DIR		"frames" | #define DUMP_FRAMES_DIR        "frames" | ||||||
| #define DUMP_AUDIO_DIR		"audio" | #define DUMP_AUDIO_DIR        "audio" | ||||||
| #define LOGS_DIR			"logs" | #define LOGS_DIR            "logs" | ||||||
| #define SHADERS_DIR 		"shaders" | #define SHADERS_DIR         "shaders" | ||||||
| #define SYSCONF_DIR 		"sysconf" | #define SYSCONF_DIR         "sysconf" | ||||||
| 
 | 
 | ||||||
| // Filenames
 | // Filenames
 | ||||||
| // Files in the directory returned by GetUserPath(D_CONFIG_IDX)
 | // Files in the directory returned by GetUserPath(D_CONFIG_IDX)
 | ||||||
| #define EMU_CONFIG		"emu.ini" | #define EMU_CONFIG        "emu.ini" | ||||||
| #define DEBUGGER_CONFIG	"debugger.ini" | #define DEBUGGER_CONFIG    "debugger.ini" | ||||||
| #define LOGGER_CONFIG	"logger.ini" | #define LOGGER_CONFIG    "logger.ini" | ||||||
| 
 | 
 | ||||||
| // Files in the directory returned by GetUserPath(D_LOGS_IDX)
 | // 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)
 | // Files in the directory returned by GetUserPath(D_SYSCONF_IDX)
 | ||||||
| #define SYSCONF	"SYSCONF" | #define SYSCONF    "SYSCONF" | ||||||
| 
 | 
 | ||||||
| #endif // _COMMON_PATHS_H_
 | #endif // _COMMON_PATHS_H_
 | ||||||
|  |  | ||||||
|  | @ -20,16 +20,16 @@ | ||||||
| ConsoleListener::ConsoleListener() | ConsoleListener::ConsoleListener() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	hConsole = NULL; |     hConsole = NULL; | ||||||
| 	bUseColor = true; |     bUseColor = true; | ||||||
| #else | #else | ||||||
| 	bUseColor = isatty(fileno(stdout)); |     bUseColor = isatty(fileno(stdout)); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ConsoleListener::~ConsoleListener() | ConsoleListener::~ConsoleListener() | ||||||
| { | { | ||||||
| 	Close(); |     Close(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // 100, 100, "Dolphin Log Console"
 | // 100, 100, "Dolphin Log Console"
 | ||||||
|  | @ -38,31 +38,31 @@ ConsoleListener::~ConsoleListener() | ||||||
| void ConsoleListener::Open(bool Hidden, int Width, int Height, const char *Title) | void ConsoleListener::Open(bool Hidden, int Width, int Height, const char *Title) | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	if (!GetConsoleWindow()) |     if (!GetConsoleWindow()) | ||||||
| 	{ |     { | ||||||
| 		// Open the console window and create the window handle for GetStdHandle()
 |         // Open the console window and create the window handle for GetStdHandle()
 | ||||||
| 		AllocConsole(); |         AllocConsole(); | ||||||
| 		// Hide
 |         // Hide
 | ||||||
| 		if (Hidden) ShowWindow(GetConsoleWindow(), SW_HIDE); |         if (Hidden) ShowWindow(GetConsoleWindow(), SW_HIDE); | ||||||
| 		// Save the window handle that AllocConsole() created
 |         // Save the window handle that AllocConsole() created
 | ||||||
| 		hConsole = GetStdHandle(STD_OUTPUT_HANDLE); |         hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||||
| 		// Set the console window title
 |         // Set the console window title
 | ||||||
| 		SetConsoleTitle(UTF8ToTStr(Title).c_str()); |         SetConsoleTitle(UTF8ToTStr(Title).c_str()); | ||||||
| 		// Set letter space
 |         // Set letter space
 | ||||||
| 		LetterSpace(80, 4000); |         LetterSpace(80, 4000); | ||||||
| 		//MoveWindow(GetConsoleWindow(), 200,200, 800,800, true);
 |         //MoveWindow(GetConsoleWindow(), 200,200, 800,800, true);
 | ||||||
| 	} |     } | ||||||
| 	else |     else | ||||||
| 	{ |     { | ||||||
| 		hConsole = GetStdHandle(STD_OUTPUT_HANDLE); |         hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||||
| 	} |     } | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConsoleListener::UpdateHandle() | void ConsoleListener::UpdateHandle() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	hConsole = GetStdHandle(STD_OUTPUT_HANDLE); |     hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -70,267 +70,267 @@ void ConsoleListener::UpdateHandle() | ||||||
| void ConsoleListener::Close() | void ConsoleListener::Close() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	if (hConsole == NULL) |     if (hConsole == NULL) | ||||||
| 		return; |         return; | ||||||
| 	FreeConsole(); |     FreeConsole(); | ||||||
| 	hConsole = NULL; |     hConsole = NULL; | ||||||
| #else | #else | ||||||
| 	fflush(NULL); |     fflush(NULL); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool ConsoleListener::IsOpen() | bool ConsoleListener::IsOpen() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	return (hConsole != NULL); |     return (hConsole != NULL); | ||||||
| #else | #else | ||||||
| 	return true; |     return true; | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|   LetterSpace: SetConsoleScreenBufferSize and SetConsoleWindowInfo are |   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) | void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst) | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	BOOL SB, SW; |     BOOL SB, SW; | ||||||
| 	if (BufferFirst) |     if (BufferFirst) | ||||||
| 	{ |     { | ||||||
| 		// Change screen buffer size
 |         // Change screen buffer size
 | ||||||
| 		COORD Co = {BufferWidth, BufferHeight}; |         COORD Co = {BufferWidth, BufferHeight}; | ||||||
| 		SB = SetConsoleScreenBufferSize(hConsole, Co); |         SB = SetConsoleScreenBufferSize(hConsole, Co); | ||||||
| 		// Change the screen buffer window size
 |         // Change the screen buffer window size
 | ||||||
| 		SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom
 |         SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom
 | ||||||
| 		SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); |         SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); | ||||||
| 	} |     } | ||||||
| 	else |     else | ||||||
| 	{ |     { | ||||||
| 		// Change the screen buffer window size
 |         // Change the screen buffer window size
 | ||||||
| 		SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom
 |         SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom
 | ||||||
| 		SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); |         SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); | ||||||
| 		// Change screen buffer size
 |         // Change screen buffer size
 | ||||||
| 		COORD Co = {BufferWidth, BufferHeight}; |         COORD Co = {BufferWidth, BufferHeight}; | ||||||
| 		SB = SetConsoleScreenBufferSize(hConsole, Co); |         SB = SetConsoleScreenBufferSize(hConsole, Co); | ||||||
| 	} |     } | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| void ConsoleListener::LetterSpace(int Width, int Height) | void ConsoleListener::LetterSpace(int Width, int Height) | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	// Get console info
 |     // Get console info
 | ||||||
| 	CONSOLE_SCREEN_BUFFER_INFO ConInfo; |     CONSOLE_SCREEN_BUFFER_INFO ConInfo; | ||||||
| 	GetConsoleScreenBufferInfo(hConsole, &ConInfo); |     GetConsoleScreenBufferInfo(hConsole, &ConInfo); | ||||||
| 
 | 
 | ||||||
| 	//
 |     //
 | ||||||
| 	int OldBufferWidth = ConInfo.dwSize.X; |     int OldBufferWidth = ConInfo.dwSize.X; | ||||||
| 	int OldBufferHeight = ConInfo.dwSize.Y; |     int OldBufferHeight = ConInfo.dwSize.Y; | ||||||
| 	int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left); |     int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left); | ||||||
| 	int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top); |     int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top); | ||||||
| 	//
 |     //
 | ||||||
| 	int NewBufferWidth = Width; |     int NewBufferWidth = Width; | ||||||
| 	int NewBufferHeight = Height; |     int NewBufferHeight = Height; | ||||||
| 	int NewScreenWidth = NewBufferWidth - 1; |     int NewScreenWidth = NewBufferWidth - 1; | ||||||
| 	int NewScreenHeight = OldScreenHeight; |     int NewScreenHeight = OldScreenHeight; | ||||||
| 
 | 
 | ||||||
| 	// Width
 |     // Width
 | ||||||
| 	BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1)); |     BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1)); | ||||||
| 	// Height
 |     // Height
 | ||||||
| 	BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1)); |     BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1)); | ||||||
| 
 | 
 | ||||||
| 	// Resize the window too
 |     // Resize the window too
 | ||||||
| 	//MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true);
 |     //MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true);
 | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| COORD ConsoleListener::GetCoordinates(int BytesRead, int BufferWidth) | COORD ConsoleListener::GetCoordinates(int BytesRead, int BufferWidth) | ||||||
| { | { | ||||||
| 	COORD Ret = {0, 0}; |     COORD Ret = {0, 0}; | ||||||
| 	// Full rows
 |     // Full rows
 | ||||||
| 	int Step = (int)floor((float)BytesRead / (float)BufferWidth); |     int Step = (int)floor((float)BytesRead / (float)BufferWidth); | ||||||
| 	Ret.Y += Step; |     Ret.Y += Step; | ||||||
| 	// Partial row
 |     // Partial row
 | ||||||
| 	Ret.X = BytesRead - (BufferWidth * Step); |     Ret.X = BytesRead - (BufferWidth * Step); | ||||||
| 	return Ret; |     return Ret; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize) | void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize) | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	// Check size
 |     // Check size
 | ||||||
| 	if (Width < 8 || Height < 12) return; |     if (Width < 8 || Height < 12) return; | ||||||
| 
 | 
 | ||||||
| 	bool DBef = true; |     bool DBef = true; | ||||||
| 	bool DAft = true; |     bool DAft = true; | ||||||
| 	std::string SLog = ""; |     std::string SLog = ""; | ||||||
| 
 | 
 | ||||||
| 	const HWND hWnd = GetConsoleWindow(); |     const HWND hWnd = GetConsoleWindow(); | ||||||
| 	const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); |     const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||||||
| 
 | 
 | ||||||
| 	// Get console info
 |     // Get console info
 | ||||||
| 	CONSOLE_SCREEN_BUFFER_INFO ConInfo; |     CONSOLE_SCREEN_BUFFER_INFO ConInfo; | ||||||
| 	GetConsoleScreenBufferInfo(hConsole, &ConInfo); |     GetConsoleScreenBufferInfo(hConsole, &ConInfo); | ||||||
| 	DWORD BufferSize = ConInfo.dwSize.X * ConInfo.dwSize.Y; |     DWORD BufferSize = ConInfo.dwSize.X * ConInfo.dwSize.Y; | ||||||
| 
 | 
 | ||||||
| 	// ---------------------------------------------------------------------
 |     // ---------------------------------------------------------------------
 | ||||||
| 	//  Save the current text
 |     //  Save the current text
 | ||||||
| 	// ------------------------
 |     // ------------------------
 | ||||||
| 	DWORD cCharsRead = 0; |     DWORD cCharsRead = 0; | ||||||
| 	COORD coordScreen = { 0, 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<TCHAR, MAX_BYTES>> Str; | ||||||
| 	std::vector<std::array<WORD, MAX_BYTES>> Attr; |     std::vector<std::array<WORD, MAX_BYTES>> Attr; | ||||||
| 
 | 
 | ||||||
| 	// ReadConsoleOutputAttribute seems to have a limit at this level
 |     // ReadConsoleOutputAttribute seems to have a limit at this level
 | ||||||
| 	static const int ReadBufferSize = MAX_BYTES - 32; |     static const int ReadBufferSize = MAX_BYTES - 32; | ||||||
| 
 | 
 | ||||||
| 	DWORD cAttrRead = ReadBufferSize; |     DWORD cAttrRead = ReadBufferSize; | ||||||
| 	DWORD BytesRead = 0; |     DWORD BytesRead = 0; | ||||||
| 	while (BytesRead < BufferSize) |     while (BytesRead < BufferSize) | ||||||
| 	{ |     { | ||||||
| 		Str.resize(Str.size() + 1); |         Str.resize(Str.size() + 1); | ||||||
| 		if (!ReadConsoleOutputCharacter(hConsole, Str.back().data(), ReadBufferSize, coordScreen, &cCharsRead)) |         if (!ReadConsoleOutputCharacter(hConsole, Str.back().data(), ReadBufferSize, coordScreen, &cCharsRead)) | ||||||
| 			SLog += StringFromFormat("WriteConsoleOutputCharacter error"); |             SLog += StringFromFormat("WriteConsoleOutputCharacter error"); | ||||||
| 
 | 
 | ||||||
| 		Attr.resize(Attr.size() + 1); |         Attr.resize(Attr.size() + 1); | ||||||
| 		if (!ReadConsoleOutputAttribute(hConsole, Attr.back().data(), ReadBufferSize, coordScreen, &cAttrRead)) |         if (!ReadConsoleOutputAttribute(hConsole, Attr.back().data(), ReadBufferSize, coordScreen, &cAttrRead)) | ||||||
| 			SLog += StringFromFormat("WriteConsoleOutputAttribute error"); |             SLog += StringFromFormat("WriteConsoleOutputAttribute error"); | ||||||
| 
 | 
 | ||||||
| 		// Break on error
 |         // Break on error
 | ||||||
| 		if (cAttrRead == 0) break; |         if (cAttrRead == 0) break; | ||||||
| 		BytesRead += cAttrRead; |         BytesRead += cAttrRead; | ||||||
| 		coordScreen = GetCoordinates(BytesRead, ConInfo.dwSize.X); |         coordScreen = GetCoordinates(BytesRead, ConInfo.dwSize.X); | ||||||
| 	} |     } | ||||||
| 	// Letter space
 |     // Letter space
 | ||||||
| 	int LWidth = (int)(floor((float)Width / 8.0f) - 1.0f); |     int LWidth = (int)(floor((float)Width / 8.0f) - 1.0f); | ||||||
| 	int LHeight = (int)(floor((float)Height / 12.0f) - 1.0f); |     int LHeight = (int)(floor((float)Height / 12.0f) - 1.0f); | ||||||
| 	int LBufWidth = LWidth + 1; |     int LBufWidth = LWidth + 1; | ||||||
| 	int LBufHeight = (int)floor((float)BufferSize / (float)LBufWidth); |     int LBufHeight = (int)floor((float)BufferSize / (float)LBufWidth); | ||||||
| 	// Change screen buffer size
 |     // Change screen buffer size
 | ||||||
| 	LetterSpace(LBufWidth, LBufHeight); |     LetterSpace(LBufWidth, LBufHeight); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	ClearScreen(true); |     ClearScreen(true); | ||||||
| 	coordScreen.Y = 0; |     coordScreen.Y = 0; | ||||||
| 	coordScreen.X = 0; |     coordScreen.X = 0; | ||||||
| 	DWORD cCharsWritten = 0; |     DWORD cCharsWritten = 0; | ||||||
| 
 | 
 | ||||||
| 	int BytesWritten = 0; |     int BytesWritten = 0; | ||||||
| 	DWORD cAttrWritten = 0; |     DWORD cAttrWritten = 0; | ||||||
| 	for (size_t i = 0; i < Attr.size(); i++) |     for (size_t i = 0; i < Attr.size(); i++) | ||||||
| 	{ |     { | ||||||
| 		if (!WriteConsoleOutputCharacter(hConsole, Str[i].data(), ReadBufferSize, coordScreen, &cCharsWritten)) |         if (!WriteConsoleOutputCharacter(hConsole, Str[i].data(), ReadBufferSize, coordScreen, &cCharsWritten)) | ||||||
| 			SLog += StringFromFormat("WriteConsoleOutputCharacter error"); |             SLog += StringFromFormat("WriteConsoleOutputCharacter error"); | ||||||
| 		if (!WriteConsoleOutputAttribute(hConsole, Attr[i].data(), ReadBufferSize, coordScreen, &cAttrWritten)) |         if (!WriteConsoleOutputAttribute(hConsole, Attr[i].data(), ReadBufferSize, coordScreen, &cAttrWritten)) | ||||||
| 			SLog += StringFromFormat("WriteConsoleOutputAttribute error"); |             SLog += StringFromFormat("WriteConsoleOutputAttribute error"); | ||||||
| 
 | 
 | ||||||
| 		BytesWritten += cAttrWritten; |         BytesWritten += cAttrWritten; | ||||||
| 		coordScreen = GetCoordinates(BytesWritten, LBufWidth); |         coordScreen = GetCoordinates(BytesWritten, LBufWidth); | ||||||
| 	}	 |     }     | ||||||
| 
 | 
 | ||||||
| 	const int OldCursor = ConInfo.dwCursorPosition.Y * ConInfo.dwSize.X + ConInfo.dwCursorPosition.X; |     const int OldCursor = ConInfo.dwCursorPosition.Y * ConInfo.dwSize.X + ConInfo.dwCursorPosition.X; | ||||||
| 	COORD Coo = GetCoordinates(OldCursor, LBufWidth); |     COORD Coo = GetCoordinates(OldCursor, LBufWidth); | ||||||
| 	SetConsoleCursorPosition(hConsole, Coo); |     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
 |     // Resize the window too
 | ||||||
| 	if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 100),Height, true); |     if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 100),Height, true); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text) | void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text) | ||||||
| { | { | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| 	/*
 |     /*
 | ||||||
| 	const int MAX_BYTES = 1024*10; |     const int MAX_BYTES = 1024*10; | ||||||
| 	char Str[MAX_BYTES]; |     char Str[MAX_BYTES]; | ||||||
| 	va_list ArgPtr; |     va_list ArgPtr; | ||||||
| 	int Cnt; |     int Cnt; | ||||||
| 	va_start(ArgPtr, Text); |     va_start(ArgPtr, Text); | ||||||
| 	Cnt = vsnprintf(Str, MAX_BYTES, Text, ArgPtr); |     Cnt = vsnprintf(Str, MAX_BYTES, Text, ArgPtr); | ||||||
| 	va_end(ArgPtr); |     va_end(ArgPtr); | ||||||
| 	*/ |     */ | ||||||
| 	DWORD cCharsWritten; |     DWORD cCharsWritten; | ||||||
| 	WORD Color; |     WORD Color; | ||||||
| 
 | 
 | ||||||
| 	switch (Level) |     switch (Level) | ||||||
| 	{ |     { | ||||||
| 	case NOTICE_LEVEL: // light green
 |     case NOTICE_LEVEL: // light green
 | ||||||
| 		Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY; |         Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY; | ||||||
| 		break; |         break; | ||||||
| 	case ERROR_LEVEL: // light red
 |     case ERROR_LEVEL: // light red
 | ||||||
| 		Color = FOREGROUND_RED | FOREGROUND_INTENSITY; |         Color = FOREGROUND_RED | FOREGROUND_INTENSITY; | ||||||
| 		break; |         break; | ||||||
| 	case WARNING_LEVEL: // light yellow
 |     case WARNING_LEVEL: // light yellow
 | ||||||
| 		Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; |         Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; | ||||||
| 		break; |         break; | ||||||
| 	case INFO_LEVEL: // cyan
 |     case INFO_LEVEL: // cyan
 | ||||||
| 		Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; |         Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; | ||||||
| 		break; |         break; | ||||||
| 	case DEBUG_LEVEL: // gray
 |     case DEBUG_LEVEL: // gray
 | ||||||
| 		Color = FOREGROUND_INTENSITY; |         Color = FOREGROUND_INTENSITY; | ||||||
| 		break; |         break; | ||||||
| 	default: // off-white
 |     default: // off-white
 | ||||||
| 		Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; |         Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; | ||||||
| 		break; |         break; | ||||||
| 	} |     } | ||||||
| 	if (strlen(Text) > 10) |     if (strlen(Text) > 10) | ||||||
| 	{ |     { | ||||||
| 		// First 10 chars white
 |         // First 10 chars white
 | ||||||
| 		SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); |         SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); | ||||||
| 		WriteConsole(hConsole, Text, 10, &cCharsWritten, NULL); |         WriteConsole(hConsole, Text, 10, &cCharsWritten, NULL); | ||||||
| 		Text += 10; |         Text += 10; | ||||||
| 	} |     } | ||||||
| 	SetConsoleTextAttribute(hConsole, Color); |     SetConsoleTextAttribute(hConsole, Color); | ||||||
| 	WriteConsole(hConsole, Text, (DWORD)strlen(Text), &cCharsWritten, NULL); |     WriteConsole(hConsole, Text, (DWORD)strlen(Text), &cCharsWritten, NULL); | ||||||
| #else | #else | ||||||
| 	char ColorAttr[16] = ""; |     char ColorAttr[16] = ""; | ||||||
| 	char ResetAttr[16] = ""; |     char ResetAttr[16] = ""; | ||||||
| 
 | 
 | ||||||
| 	if (bUseColor) |     if (bUseColor) | ||||||
| 	{ |     { | ||||||
| 		strcpy(ResetAttr, "\033[0m"); |         strcpy(ResetAttr, "\033[0m"); | ||||||
| 		switch (Level) |         switch (Level) | ||||||
| 		{ |         { | ||||||
| 		case NOTICE_LEVEL: // light green
 |         case NOTICE_LEVEL: // light green
 | ||||||
| 			strcpy(ColorAttr, "\033[92m"); |             strcpy(ColorAttr, "\033[92m"); | ||||||
| 			break; |             break; | ||||||
| 		case ERROR_LEVEL: // light red
 |         case ERROR_LEVEL: // light red
 | ||||||
| 			strcpy(ColorAttr, "\033[91m"); |             strcpy(ColorAttr, "\033[91m"); | ||||||
| 			break; |             break; | ||||||
| 		case WARNING_LEVEL: // light yellow
 |         case WARNING_LEVEL: // light yellow
 | ||||||
| 			strcpy(ColorAttr, "\033[93m"); |             strcpy(ColorAttr, "\033[93m"); | ||||||
| 			break; |             break; | ||||||
| 		default: |         default: | ||||||
| 			break; |             break; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| 	fprintf(stderr, "%s%s%s", ColorAttr, Text, ResetAttr); |     fprintf(stderr, "%s%s%s", ColorAttr, Text, ResetAttr); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| // Clear console screen
 | // Clear console screen
 | ||||||
| void ConsoleListener::ClearScreen(bool Cursor) | void ConsoleListener::ClearScreen(bool Cursor) | ||||||
| {  | {  | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| 	COORD coordScreen = { 0, 0 };  |     COORD coordScreen = { 0, 0 };  | ||||||
| 	DWORD cCharsWritten;  |     DWORD cCharsWritten;  | ||||||
| 	CONSOLE_SCREEN_BUFFER_INFO csbi;  |     CONSOLE_SCREEN_BUFFER_INFO csbi;  | ||||||
| 	DWORD dwConSize;  |     DWORD dwConSize;  | ||||||
| 
 | 
 | ||||||
| 	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);  |     HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);  | ||||||
| 
 | 
 | ||||||
| 	GetConsoleScreenBufferInfo(hConsole, &csbi);  |     GetConsoleScreenBufferInfo(hConsole, &csbi);  | ||||||
| 	dwConSize = csbi.dwSize.X * csbi.dwSize.Y; |     dwConSize = csbi.dwSize.X * csbi.dwSize.Y; | ||||||
| 	// Write space to the entire console
 |     // Write space to the entire console
 | ||||||
| 	FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);  |     FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);  | ||||||
| 	GetConsoleScreenBufferInfo(hConsole, &csbi);  |     GetConsoleScreenBufferInfo(hConsole, &csbi);  | ||||||
| 	FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten); |     FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten); | ||||||
| 	// Reset cursor
 |     // Reset cursor
 | ||||||
| 	if (Cursor) SetConsoleCursorPosition(hConsole, coordScreen);  |     if (Cursor) SetConsoleCursorPosition(hConsole, coordScreen);  | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -14,28 +14,28 @@ | ||||||
| class ConsoleListener : public LogListener | class ConsoleListener : public LogListener | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	ConsoleListener(); |     ConsoleListener(); | ||||||
| 	~ConsoleListener(); |     ~ConsoleListener(); | ||||||
| 
 | 
 | ||||||
| 	void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console"); |     void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console"); | ||||||
| 	void UpdateHandle(); |     void UpdateHandle(); | ||||||
| 	void Close(); |     void Close(); | ||||||
| 	bool IsOpen(); |     bool IsOpen(); | ||||||
| 	void LetterSpace(int Width, int Height); |     void LetterSpace(int Width, int Height); | ||||||
| 	void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst); |     void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst); | ||||||
| 	void PixelSpace(int Left, int Top, int Width, int Height, bool); |     void PixelSpace(int Left, int Top, int Width, int Height, bool); | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	COORD GetCoordinates(int BytesRead, int BufferWidth); |     COORD GetCoordinates(int BytesRead, int BufferWidth); | ||||||
| #endif | #endif | ||||||
| 	void Log(LogTypes::LOG_LEVELS, const char *Text); |     void Log(LogTypes::LOG_LEVELS, const char *Text); | ||||||
| 	void ClearScreen(bool Cursor = true); |     void ClearScreen(bool Cursor = true); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	HWND GetHwnd(void); |     HWND GetHwnd(void); | ||||||
| 	HANDLE hConsole; |     HANDLE hConsole; | ||||||
| #endif | #endif | ||||||
| 	bool bUseColor; |     bool bUseColor; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif  // _CONSOLELISTENER_H
 | #endif  // _CONSOLELISTENER_H
 | ||||||
|  |  | ||||||
|  | @ -11,69 +11,69 @@ | ||||||
| 
 | 
 | ||||||
| enum CPUVendor | enum CPUVendor | ||||||
| { | { | ||||||
| 	VENDOR_INTEL = 0, |     VENDOR_INTEL = 0, | ||||||
| 	VENDOR_AMD = 1, |     VENDOR_AMD = 1, | ||||||
| 	VENDOR_ARM = 2, |     VENDOR_ARM = 2, | ||||||
| 	VENDOR_OTHER = 3, |     VENDOR_OTHER = 3, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct CPUInfo | struct CPUInfo | ||||||
| { | { | ||||||
| 	CPUVendor vendor; |     CPUVendor vendor; | ||||||
| 
 | 
 | ||||||
| 	char cpu_string[0x21]; |     char cpu_string[0x21]; | ||||||
| 	char brand_string[0x41]; |     char brand_string[0x41]; | ||||||
| 	bool OS64bit; |     bool OS64bit; | ||||||
| 	bool CPU64bit; |     bool CPU64bit; | ||||||
| 	bool Mode64bit; |     bool Mode64bit; | ||||||
| 
 | 
 | ||||||
| 	bool HTT; |     bool HTT; | ||||||
| 	int num_cores; |     int num_cores; | ||||||
| 	int logical_cpu_count; |     int logical_cpu_count; | ||||||
| 
 | 
 | ||||||
| 	bool bSSE; |     bool bSSE; | ||||||
| 	bool bSSE2; |     bool bSSE2; | ||||||
| 	bool bSSE3; |     bool bSSE3; | ||||||
| 	bool bSSSE3; |     bool bSSSE3; | ||||||
| 	bool bPOPCNT; |     bool bPOPCNT; | ||||||
| 	bool bSSE4_1; |     bool bSSE4_1; | ||||||
| 	bool bSSE4_2; |     bool bSSE4_2; | ||||||
| 	bool bLZCNT; |     bool bLZCNT; | ||||||
| 	bool bSSE4A; |     bool bSSE4A; | ||||||
| 	bool bAVX; |     bool bAVX; | ||||||
| 	bool bAES; |     bool bAES; | ||||||
| 	bool bLAHFSAHF64; |     bool bLAHFSAHF64; | ||||||
| 	bool bLongMode; |     bool bLongMode; | ||||||
| 
 | 
 | ||||||
| 	// ARM specific CPUInfo
 |     // ARM specific CPUInfo
 | ||||||
| 	bool bSwp; |     bool bSwp; | ||||||
| 	bool bHalf; |     bool bHalf; | ||||||
| 	bool bThumb; |     bool bThumb; | ||||||
| 	bool bFastMult; |     bool bFastMult; | ||||||
| 	bool bVFP; |     bool bVFP; | ||||||
| 	bool bEDSP; |     bool bEDSP; | ||||||
| 	bool bThumbEE; |     bool bThumbEE; | ||||||
| 	bool bNEON; |     bool bNEON; | ||||||
| 	bool bVFPv3; |     bool bVFPv3; | ||||||
| 	bool bTLS; |     bool bTLS; | ||||||
| 	bool bVFPv4; |     bool bVFPv4; | ||||||
| 	bool bIDIVa; |     bool bIDIVa; | ||||||
| 	bool bIDIVt; |     bool bIDIVt; | ||||||
| 	bool bArmV7;  // enable MOVT, MOVW etc
 |     bool bArmV7;  // enable MOVT, MOVW etc
 | ||||||
| 
 | 
 | ||||||
| 	// ARMv8 specific
 |     // ARMv8 specific
 | ||||||
| 	bool bFP; |     bool bFP; | ||||||
| 	bool bASIMD; |     bool bASIMD; | ||||||
| 
 | 
 | ||||||
| 	// Call Detect()
 |     // Call Detect()
 | ||||||
| 	explicit CPUInfo(); |     explicit CPUInfo(); | ||||||
| 
 | 
 | ||||||
| 	// Turn the cpu info into a string we can show
 |     // Turn the cpu info into a string we can show
 | ||||||
| 	std::string Summarize(); |     std::string Summarize(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	// Detects the various cpu features
 |     // Detects the various cpu features
 | ||||||
| 	void Detect(); |     void Detect(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| extern CPUInfo cpu_info; | extern CPUInfo cpu_info; | ||||||
|  |  | ||||||
|  | @ -7,33 +7,33 @@ | ||||||
| class DebugInterface | class DebugInterface | ||||||
| { | { | ||||||
| protected: | protected: | ||||||
| 	virtual ~DebugInterface() {} |     virtual ~DebugInterface() {} | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
| 	virtual void disasm(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} |     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 void getRawMemoryString(int /*memory*/, unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} | ||||||
| 	virtual int getInstructionSize(int /*instruction*/) {return 1;} |     virtual int getInstructionSize(int /*instruction*/) {return 1;} | ||||||
| 	virtual bool isAlive() {return true;} |     virtual bool isAlive() {return true;} | ||||||
| 	virtual bool isBreakpoint(unsigned int /*address*/) {return false;} |     virtual bool isBreakpoint(unsigned int /*address*/) {return false;} | ||||||
| 	virtual void setBreakpoint(unsigned int /*address*/){} |     virtual void setBreakpoint(unsigned int /*address*/){} | ||||||
| 	virtual void clearBreakpoint(unsigned int /*address*/){} |     virtual void clearBreakpoint(unsigned int /*address*/){} | ||||||
| 	virtual void clearAllBreakpoints() {} |     virtual void clearAllBreakpoints() {} | ||||||
| 	virtual void toggleBreakpoint(unsigned int /*address*/){} |     virtual void toggleBreakpoint(unsigned int /*address*/){} | ||||||
| 	virtual bool isMemCheck(unsigned int /*address*/) {return false;} |     virtual bool isMemCheck(unsigned int /*address*/) {return false;} | ||||||
| 	virtual void toggleMemCheck(unsigned int /*address*/){} |     virtual void toggleMemCheck(unsigned int /*address*/){} | ||||||
| 	virtual unsigned int readMemory(unsigned int /*address*/){return 0;} |     virtual unsigned int readMemory(unsigned int /*address*/){return 0;} | ||||||
| 	virtual void writeExtraMemory(int /*memory*/, unsigned int /*value*/, unsigned int /*address*/) {} |     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 readExtraMemory(int /*memory*/, unsigned int /*address*/){return 0;} | ||||||
| 	virtual unsigned int readInstruction(unsigned int /*address*/){return 0;} |     virtual unsigned int readInstruction(unsigned int /*address*/){return 0;} | ||||||
| 	virtual unsigned int getPC() {return 0;} |     virtual unsigned int getPC() {return 0;} | ||||||
| 	virtual void setPC(unsigned int /*address*/) {} |     virtual void setPC(unsigned int /*address*/) {} | ||||||
| 	virtual void step() {} |     virtual void step() {} | ||||||
| 	virtual void runToBreakpoint() {} |     virtual void runToBreakpoint() {} | ||||||
| 	virtual void breakNow() {} |     virtual void breakNow() {} | ||||||
| 	virtual void insertBLR(unsigned int /*address*/, unsigned int /*value*/) {} |     virtual void insertBLR(unsigned int /*address*/, unsigned int /*value*/) {} | ||||||
| 	virtual void showJitResults(unsigned int /*address*/) {}; |     virtual void showJitResults(unsigned int /*address*/) {}; | ||||||
| 	virtual int getColor(unsigned int /*address*/){return 0xFFFFFFFF;} |     virtual int getColor(unsigned int /*address*/){return 0xFFFFFFFF;} | ||||||
| 	virtual std::string getDescription(unsigned int /*address*/) = 0; |     virtual std::string getDescription(unsigned int /*address*/) = 0; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -48,8 +48,8 @@ public: | ||||||
|     /// Swap buffers to display the next frame
 |     /// Swap buffers to display the next frame
 | ||||||
|     virtual void SwapBuffers() = 0; |     virtual void SwapBuffers() = 0; | ||||||
| 
 | 
 | ||||||
| 	/// Polls window events
 |     /// Polls window events
 | ||||||
| 	virtual void PollEvents() = 0; |     virtual void PollEvents() = 0; | ||||||
| 
 | 
 | ||||||
|     /// Makes the graphics context current for the caller thread
 |     /// Makes the graphics context current for the caller thread
 | ||||||
|     virtual void MakeCurrent() = 0; |     virtual void MakeCurrent() = 0; | ||||||
|  |  | ||||||
|  | @ -30,18 +30,18 @@ using namespace std; | ||||||
| void PCSTR2LPTSTR( PCSTR lpszIn, LPTSTR lpszOut ) | void PCSTR2LPTSTR( PCSTR lpszIn, LPTSTR lpszOut ) | ||||||
| { | { | ||||||
| #if defined(UNICODE)||defined(_UNICODE) | #if defined(UNICODE)||defined(_UNICODE) | ||||||
| 	ULONG index = 0;  |     ULONG index = 0;  | ||||||
| 	PCSTR lpAct = lpszIn; |     PCSTR lpAct = lpszIn; | ||||||
| 
 | 
 | ||||||
| 	for( ; ; lpAct++ ) |     for( ; ; lpAct++ ) | ||||||
| 	{ |     { | ||||||
| 		lpszOut[index++] = (TCHAR)(*lpAct); |         lpszOut[index++] = (TCHAR)(*lpAct); | ||||||
| 		if ( *lpAct == 0 ) |         if ( *lpAct == 0 ) | ||||||
| 			break; |             break; | ||||||
| 	}  |     }  | ||||||
| #else | #else | ||||||
| 	// This is trivial :)
 |     // This is trivial :)
 | ||||||
| 	strcpy( lpszOut, lpszIn ); |     strcpy( lpszOut, lpszIn ); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -50,184 +50,184 @@ void PCSTR2LPTSTR( PCSTR lpszIn, LPTSTR lpszOut ) | ||||||
| // Note: There is no size check for lpszSymbolPath!
 | // Note: There is no size check for lpszSymbolPath!
 | ||||||
| static void InitSymbolPath( PSTR lpszSymbolPath, PCSTR lpszIniPath ) | static void InitSymbolPath( PSTR lpszSymbolPath, PCSTR lpszIniPath ) | ||||||
| { | { | ||||||
| 	CHAR lpszPath[BUFFERSIZE]; |     CHAR lpszPath[BUFFERSIZE]; | ||||||
| 
 | 
 | ||||||
| 	// Creating the default path
 |     // Creating the default path
 | ||||||
| 	// ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%SYSTEMROOT%;%SYSTEMROOT%\System32;"
 |     // ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%SYSTEMROOT%;%SYSTEMROOT%\System32;"
 | ||||||
| 	strcpy( lpszSymbolPath, "." ); |     strcpy( lpszSymbolPath, "." ); | ||||||
| 
 | 
 | ||||||
| 	// environment variable _NT_SYMBOL_PATH
 |     // environment variable _NT_SYMBOL_PATH
 | ||||||
| 	if ( GetEnvironmentVariableA( "_NT_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) |     if ( GetEnvironmentVariableA( "_NT_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) | ||||||
| 	{ |     { | ||||||
| 		strcat( lpszSymbolPath, ";" ); |         strcat( lpszSymbolPath, ";" ); | ||||||
| 		strcat( lpszSymbolPath, lpszPath ); |         strcat( lpszSymbolPath, lpszPath ); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// environment variable _NT_ALTERNATE_SYMBOL_PATH
 |     // environment variable _NT_ALTERNATE_SYMBOL_PATH
 | ||||||
| 	if ( GetEnvironmentVariableA( "_NT_ALTERNATE_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) |     if ( GetEnvironmentVariableA( "_NT_ALTERNATE_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) | ||||||
| 	{ |     { | ||||||
| 		strcat( lpszSymbolPath, ";" ); |         strcat( lpszSymbolPath, ";" ); | ||||||
| 		strcat( lpszSymbolPath, lpszPath ); |         strcat( lpszSymbolPath, lpszPath ); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// environment variable SYSTEMROOT
 |     // environment variable SYSTEMROOT
 | ||||||
| 	if ( GetEnvironmentVariableA( "SYSTEMROOT", lpszPath, BUFFERSIZE ) ) |     if ( GetEnvironmentVariableA( "SYSTEMROOT", lpszPath, BUFFERSIZE ) ) | ||||||
| 	{ |     { | ||||||
| 		strcat( lpszSymbolPath, ";" ); |         strcat( lpszSymbolPath, ";" ); | ||||||
| 		strcat( lpszSymbolPath, lpszPath ); |         strcat( lpszSymbolPath, lpszPath ); | ||||||
| 		strcat( lpszSymbolPath, ";" ); |         strcat( lpszSymbolPath, ";" ); | ||||||
| 
 | 
 | ||||||
| 		// SYSTEMROOT\System32
 |         // SYSTEMROOT\System32
 | ||||||
| 		strcat( lpszSymbolPath, lpszPath ); |         strcat( lpszSymbolPath, lpszPath ); | ||||||
| 		strcat( lpszSymbolPath, "\\System32" ); |         strcat( lpszSymbolPath, "\\System32" ); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// Add user defined path
 |     // Add user defined path
 | ||||||
| 	if ( lpszIniPath != NULL ) |     if ( lpszIniPath != NULL ) | ||||||
| 		if ( lpszIniPath[0] != '\0' ) |         if ( lpszIniPath[0] != '\0' ) | ||||||
| 		{ |         { | ||||||
| 			strcat( lpszSymbolPath, ";" ); |             strcat( lpszSymbolPath, ";" ); | ||||||
| 			strcat( lpszSymbolPath, lpszIniPath ); |             strcat( lpszSymbolPath, lpszIniPath ); | ||||||
| 		} |         } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Uninitialize the loaded symbol files
 | // Uninitialize the loaded symbol files
 | ||||||
| BOOL UninitSymInfo() { | BOOL UninitSymInfo() { | ||||||
| 	return SymCleanup( GetCurrentProcess() ); |     return SymCleanup( GetCurrentProcess() ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Initializes the symbol files
 | // Initializes the symbol files
 | ||||||
| BOOL InitSymInfo( PCSTR lpszInitialSymbolPath ) | BOOL InitSymInfo( PCSTR lpszInitialSymbolPath ) | ||||||
| { | { | ||||||
| 	CHAR     lpszSymbolPath[BUFFERSIZE]; |     CHAR     lpszSymbolPath[BUFFERSIZE]; | ||||||
| 	DWORD    symOptions = SymGetOptions(); |     DWORD    symOptions = SymGetOptions(); | ||||||
| 
 | 
 | ||||||
| 	symOptions |= SYMOPT_LOAD_LINES;  |     symOptions |= SYMOPT_LOAD_LINES;  | ||||||
| 	symOptions &= ~SYMOPT_UNDNAME; |     symOptions &= ~SYMOPT_UNDNAME; | ||||||
| 	SymSetOptions( symOptions ); |     SymSetOptions( symOptions ); | ||||||
| 	InitSymbolPath( lpszSymbolPath, lpszInitialSymbolPath ); |     InitSymbolPath( lpszSymbolPath, lpszInitialSymbolPath ); | ||||||
| 
 | 
 | ||||||
| 	return SymInitialize( GetCurrentProcess(), lpszSymbolPath, TRUE); |     return SymInitialize( GetCurrentProcess(), lpszSymbolPath, TRUE); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Get the module name from a given address
 | // Get the module name from a given address
 | ||||||
| static BOOL GetModuleNameFromAddress( UINT address, LPTSTR lpszModule ) | static BOOL GetModuleNameFromAddress( UINT address, LPTSTR lpszModule ) | ||||||
| { | { | ||||||
| 	BOOL              ret = FALSE; |     BOOL              ret = FALSE; | ||||||
| 	IMAGEHLP_MODULE   moduleInfo; |     IMAGEHLP_MODULE   moduleInfo; | ||||||
| 
 | 
 | ||||||
| 	::ZeroMemory( &moduleInfo, sizeof(moduleInfo) ); |     ::ZeroMemory( &moduleInfo, sizeof(moduleInfo) ); | ||||||
| 	moduleInfo.SizeOfStruct = sizeof(moduleInfo); |     moduleInfo.SizeOfStruct = sizeof(moduleInfo); | ||||||
| 
 | 
 | ||||||
| 	if ( SymGetModuleInfo( GetCurrentProcess(), (DWORD)address, &moduleInfo ) ) |     if ( SymGetModuleInfo( GetCurrentProcess(), (DWORD)address, &moduleInfo ) ) | ||||||
| 	{ |     { | ||||||
| 		// Got it!
 |         // Got it!
 | ||||||
| 		PCSTR2LPTSTR( moduleInfo.ModuleName, lpszModule ); |         PCSTR2LPTSTR( moduleInfo.ModuleName, lpszModule ); | ||||||
| 		ret = TRUE; |         ret = TRUE; | ||||||
| 	} |     } | ||||||
| 	else |     else | ||||||
| 		// Not found :(
 |         // Not found :(
 | ||||||
| 		_tcscpy( lpszModule, _T("?") ); |         _tcscpy( lpszModule, _T("?") ); | ||||||
| 
 | 
 | ||||||
| 	return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Get function prototype and parameter info from ip address and stack address
 | // Get function prototype and parameter info from ip address and stack address
 | ||||||
| static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, LPTSTR lpszSymbol ) | static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, LPTSTR lpszSymbol ) | ||||||
| { | { | ||||||
| 	BOOL              ret = FALSE; |     BOOL              ret = FALSE; | ||||||
| 	DWORD             dwSymSize = 10000; |     DWORD             dwSymSize = 10000; | ||||||
| 	TCHAR             lpszUnDSymbol[BUFFERSIZE]=_T("?"); |     TCHAR             lpszUnDSymbol[BUFFERSIZE]=_T("?"); | ||||||
| 	CHAR              lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?"; |     CHAR              lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?"; | ||||||
| 	LPTSTR            lpszParamSep = NULL; |     LPTSTR            lpszParamSep = NULL; | ||||||
| 	LPTSTR            lpszParsed = lpszUnDSymbol; |     LPTSTR            lpszParsed = lpszUnDSymbol; | ||||||
| 	PIMAGEHLP_SYMBOL  pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize ); |     PIMAGEHLP_SYMBOL  pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize ); | ||||||
| 
 | 
 | ||||||
| 	::ZeroMemory( pSym, dwSymSize ); |     ::ZeroMemory( pSym, dwSymSize ); | ||||||
| 	pSym->SizeOfStruct = dwSymSize; |     pSym->SizeOfStruct = dwSymSize; | ||||||
| 	pSym->MaxNameLength = dwSymSize - sizeof(IMAGEHLP_SYMBOL); |     pSym->MaxNameLength = dwSymSize - sizeof(IMAGEHLP_SYMBOL); | ||||||
| 
 | 
 | ||||||
| 	// Set the default to unknown
 |     // Set the default to unknown
 | ||||||
| 	_tcscpy( lpszSymbol, _T("?") ); |     _tcscpy( lpszSymbol, _T("?") ); | ||||||
| 
 | 
 | ||||||
| 	// Get symbol info for IP
 |     // Get symbol info for IP
 | ||||||
| #ifndef _M_X64 | #ifndef _M_X64 | ||||||
| 	DWORD             dwDisp = 0; |     DWORD             dwDisp = 0; | ||||||
| 	if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, &dwDisp, pSym ) ) |     if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, &dwDisp, pSym ) ) | ||||||
| #else  | #else  | ||||||
| 	//makes it compile but hell im not sure if this works...
 |     //makes it compile but hell im not sure if this works...
 | ||||||
| 	DWORD64           dwDisp = 0; |     DWORD64           dwDisp = 0; | ||||||
| 	if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) ) |     if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) ) | ||||||
| #endif | #endif | ||||||
| 	{ |     { | ||||||
| 		// Make the symbol readable for humans
 |         // Make the symbol readable for humans
 | ||||||
| 		UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE,  |         UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE,  | ||||||
| 			UNDNAME_COMPLETE |  |             UNDNAME_COMPLETE |  | ||||||
| 			UNDNAME_NO_THISTYPE | |             UNDNAME_NO_THISTYPE | | ||||||
| 			UNDNAME_NO_SPECIAL_SYMS | |             UNDNAME_NO_SPECIAL_SYMS | | ||||||
| 			UNDNAME_NO_MEMBER_TYPE | |             UNDNAME_NO_MEMBER_TYPE | | ||||||
| 			UNDNAME_NO_MS_KEYWORDS | |             UNDNAME_NO_MS_KEYWORDS | | ||||||
| 			UNDNAME_NO_ACCESS_SPECIFIERS ); |             UNDNAME_NO_ACCESS_SPECIFIERS ); | ||||||
| 
 | 
 | ||||||
| 		// Symbol information is ANSI string
 |         // Symbol information is ANSI string
 | ||||||
| 		PCSTR2LPTSTR( lpszNonUnicodeUnDSymbol, lpszUnDSymbol ); |         PCSTR2LPTSTR( lpszNonUnicodeUnDSymbol, lpszUnDSymbol ); | ||||||
| 
 | 
 | ||||||
| 		// I am just smarter than the symbol file :)
 |         // I am just smarter than the symbol file :)
 | ||||||
| 		if ( _tcscmp(lpszUnDSymbol, _T("_WinMain@16")) == 0 ) |         if ( _tcscmp(lpszUnDSymbol, _T("_WinMain@16")) == 0 ) | ||||||
| 			_tcscpy(lpszUnDSymbol, _T("WinMain(HINSTANCE,HINSTANCE,LPCTSTR,int)")); |             _tcscpy(lpszUnDSymbol, _T("WinMain(HINSTANCE,HINSTANCE,LPCTSTR,int)")); | ||||||
| 		else |         else | ||||||
| 			if ( _tcscmp(lpszUnDSymbol, _T("_main")) == 0 ) |             if ( _tcscmp(lpszUnDSymbol, _T("_main")) == 0 ) | ||||||
| 				_tcscpy(lpszUnDSymbol, _T("main(int,TCHAR * *)")); |                 _tcscpy(lpszUnDSymbol, _T("main(int,TCHAR * *)")); | ||||||
| 			else |             else | ||||||
| 				if ( _tcscmp(lpszUnDSymbol, _T("_mainCRTStartup")) == 0 ) |                 if ( _tcscmp(lpszUnDSymbol, _T("_mainCRTStartup")) == 0 ) | ||||||
| 					_tcscpy(lpszUnDSymbol, _T("mainCRTStartup()")); |                     _tcscpy(lpszUnDSymbol, _T("mainCRTStartup()")); | ||||||
| 				else |                 else | ||||||
| 					if ( _tcscmp(lpszUnDSymbol, _T("_wmain")) == 0 ) |                     if ( _tcscmp(lpszUnDSymbol, _T("_wmain")) == 0 ) | ||||||
| 						_tcscpy(lpszUnDSymbol, _T("wmain(int,TCHAR * *,TCHAR * *)")); |                         _tcscpy(lpszUnDSymbol, _T("wmain(int,TCHAR * *,TCHAR * *)")); | ||||||
| 					else |                     else | ||||||
| 						if ( _tcscmp(lpszUnDSymbol, _T("_wmainCRTStartup")) == 0 ) |                         if ( _tcscmp(lpszUnDSymbol, _T("_wmainCRTStartup")) == 0 ) | ||||||
| 							_tcscpy(lpszUnDSymbol, _T("wmainCRTStartup()")); |                             _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
 |         // Let's go through the stack, and modify the function prototype, and insert the actual
 | ||||||
| 		// parameter values from the stack
 |         // parameter values from the stack
 | ||||||
| 		if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == NULL && _tcsstr( lpszUnDSymbol, _T("()") ) == NULL) |         if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == NULL && _tcsstr( lpszUnDSymbol, _T("()") ) == NULL) | ||||||
| 		{ |         { | ||||||
| 			ULONG index = 0; |             ULONG index = 0; | ||||||
| 			for( ; ; index++ ) |             for( ; ; index++ ) | ||||||
| 			{ |             { | ||||||
| 				lpszParamSep = _tcschr( lpszParsed, _T(',') ); |                 lpszParamSep = _tcschr( lpszParsed, _T(',') ); | ||||||
| 				if ( lpszParamSep == NULL ) |                 if ( lpszParamSep == NULL ) | ||||||
| 					break; |                     break; | ||||||
| 
 | 
 | ||||||
| 				*lpszParamSep = _T('\0'); |                 *lpszParamSep = _T('\0'); | ||||||
| 
 | 
 | ||||||
| 				_tcscat( lpszSymbol, lpszParsed ); |                 _tcscat( lpszSymbol, lpszParsed ); | ||||||
| 				_stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X,"), *((ULONG*)(stackAddress) + 2 + index) ); |                 _stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X,"), *((ULONG*)(stackAddress) + 2 + index) ); | ||||||
| 
 | 
 | ||||||
| 				lpszParsed = lpszParamSep + 1; |                 lpszParsed = lpszParamSep + 1; | ||||||
| 			} |             } | ||||||
| 
 | 
 | ||||||
| 			lpszParamSep = _tcschr( lpszParsed, _T(')') ); |             lpszParamSep = _tcschr( lpszParsed, _T(')') ); | ||||||
| 			if ( lpszParamSep != NULL ) |             if ( lpszParamSep != NULL ) | ||||||
| 			{ |             { | ||||||
| 				*lpszParamSep = _T('\0'); |                 *lpszParamSep = _T('\0'); | ||||||
| 
 | 
 | ||||||
| 				_tcscat( lpszSymbol, lpszParsed ); |                 _tcscat( lpszSymbol, lpszParsed ); | ||||||
| 				_stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X)"), *((ULONG*)(stackAddress) + 2 + index) ); |                 _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; |         ret = TRUE; | ||||||
| 	}  |     }  | ||||||
| 	GlobalFree( pSym ); |     GlobalFree( pSym ); | ||||||
| 
 | 
 | ||||||
| 	return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Get source file name and line number from IP address
 | // Get source file name and line number from IP address
 | ||||||
|  | @ -236,198 +236,198 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L | ||||||
| //                       "address"
 | //                       "address"
 | ||||||
| static BOOL GetSourceInfoFromAddress( UINT address, LPTSTR lpszSourceInfo ) | static BOOL GetSourceInfoFromAddress( UINT address, LPTSTR lpszSourceInfo ) | ||||||
| { | { | ||||||
| 	BOOL           ret = FALSE; |     BOOL           ret = FALSE; | ||||||
| 	IMAGEHLP_LINE  lineInfo; |     IMAGEHLP_LINE  lineInfo; | ||||||
| 	DWORD          dwDisp; |     DWORD          dwDisp; | ||||||
| 	TCHAR          lpszFileName[BUFFERSIZE] = _T(""); |     TCHAR          lpszFileName[BUFFERSIZE] = _T(""); | ||||||
| 	TCHAR          lpModuleInfo[BUFFERSIZE] = _T(""); |     TCHAR          lpModuleInfo[BUFFERSIZE] = _T(""); | ||||||
| 
 | 
 | ||||||
| 	_tcscpy( lpszSourceInfo, _T("?(?)") ); |     _tcscpy( lpszSourceInfo, _T("?(?)") ); | ||||||
| 
 | 
 | ||||||
| 	::ZeroMemory( &lineInfo, sizeof( lineInfo ) ); |     ::ZeroMemory( &lineInfo, sizeof( lineInfo ) ); | ||||||
| 	lineInfo.SizeOfStruct = sizeof( lineInfo ); |     lineInfo.SizeOfStruct = sizeof( lineInfo ); | ||||||
| 
 | 
 | ||||||
| 	if ( SymGetLineFromAddr( GetCurrentProcess(), address, &dwDisp, &lineInfo ) ) |     if ( SymGetLineFromAddr( GetCurrentProcess(), address, &dwDisp, &lineInfo ) ) | ||||||
| 	{ |     { | ||||||
| 		// Got it. Let's use "sourcefile(linenumber)" format
 |         // Got it. Let's use "sourcefile(linenumber)" format
 | ||||||
| 		PCSTR2LPTSTR( lineInfo.FileName, lpszFileName ); |         PCSTR2LPTSTR( lineInfo.FileName, lpszFileName ); | ||||||
| 		TCHAR fname[_MAX_FNAME]; |         TCHAR fname[_MAX_FNAME]; | ||||||
| 		TCHAR ext[_MAX_EXT]; |         TCHAR ext[_MAX_EXT]; | ||||||
| 		_tsplitpath(lpszFileName, NULL, NULL, fname, ext); |         _tsplitpath(lpszFileName, NULL, NULL, fname, ext); | ||||||
| 		_stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber ); |         _stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber ); | ||||||
| 		ret = TRUE; |         ret = TRUE; | ||||||
| 	} |     } | ||||||
| 	else |     else | ||||||
| 	{ |     { | ||||||
| 		// There is no source file information. :(
 |         // There is no source file information. :(
 | ||||||
| 		// Let's use the "modulename!address" format
 |         // Let's use the "modulename!address" format
 | ||||||
| 		GetModuleNameFromAddress( address, lpModuleInfo ); |         GetModuleNameFromAddress( address, lpModuleInfo ); | ||||||
| 
 | 
 | ||||||
| 		if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0')) |         if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0')) | ||||||
| 			// There is no modulename information. :((
 |             // There is no modulename information. :((
 | ||||||
| 			// Let's use the "address" format
 |             // Let's use the "address" format
 | ||||||
| 			_stprintf( lpszSourceInfo, _T("0x%08X"), address ); |             _stprintf( lpszSourceInfo, _T("0x%08X"), address ); | ||||||
| 		else |         else | ||||||
| 			_stprintf( lpszSourceInfo, _T("%s!0x%08X"), lpModuleInfo, address ); |             _stprintf( lpszSourceInfo, _T("%s!0x%08X"), lpModuleInfo, address ); | ||||||
| 
 | 
 | ||||||
| 		ret = FALSE; |         ret = FALSE; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PrintFunctionAndSourceInfo(FILE* file, const STACKFRAME& callstack) | void PrintFunctionAndSourceInfo(FILE* file, const STACKFRAME& callstack) | ||||||
| { | { | ||||||
| 	TCHAR symInfo[BUFFERSIZE] = _T("?"); |     TCHAR symInfo[BUFFERSIZE] = _T("?"); | ||||||
| 	TCHAR srcInfo[BUFFERSIZE] = _T("?"); |     TCHAR srcInfo[BUFFERSIZE] = _T("?"); | ||||||
| 
 | 
 | ||||||
| 	GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo); |     GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo); | ||||||
| 	GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo); |     GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo); | ||||||
| 	etfprint(file, "     " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n"); |     etfprint(file, "     " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void StackTrace( HANDLE hThread, const char* lpszMessage, FILE *file ) | void StackTrace( HANDLE hThread, const char* lpszMessage, FILE *file ) | ||||||
| { | { | ||||||
| 	STACKFRAME     callStack; |     STACKFRAME     callStack; | ||||||
| 	BOOL           bResult; |     BOOL           bResult; | ||||||
| 	CONTEXT        context; |     CONTEXT        context; | ||||||
| 	HANDLE         hProcess = GetCurrentProcess(); |     HANDLE         hProcess = GetCurrentProcess(); | ||||||
| 
 | 
 | ||||||
| 	// If it's not this thread, let's suspend it, and resume it at the end
 |     // If it's not this thread, let's suspend it, and resume it at the end
 | ||||||
| 	if ( hThread != GetCurrentThread() ) |     if ( hThread != GetCurrentThread() ) | ||||||
| 		if ( SuspendThread( hThread ) == -1 ) |         if ( SuspendThread( hThread ) == -1 ) | ||||||
| 		{ |         { | ||||||
| 			// whaaat ?!
 |             // whaaat ?!
 | ||||||
| 			etfprint(file, "Call stack info failed\n"); |             etfprint(file, "Call stack info failed\n"); | ||||||
| 			return; |             return; | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		::ZeroMemory( &context, sizeof(context) ); |         ::ZeroMemory( &context, sizeof(context) ); | ||||||
| 		context.ContextFlags = CONTEXT_FULL; |         context.ContextFlags = CONTEXT_FULL; | ||||||
| 
 | 
 | ||||||
| 		if ( !GetThreadContext( hThread, &context ) ) |         if ( !GetThreadContext( hThread, &context ) ) | ||||||
| 		{ |         { | ||||||
| 			etfprint(file, "Call stack info failed\n"); |             etfprint(file, "Call stack info failed\n"); | ||||||
| 			return; |             return; | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		::ZeroMemory( &callStack, sizeof(callStack) ); |         ::ZeroMemory( &callStack, sizeof(callStack) ); | ||||||
| #ifndef _M_X64 | #ifndef _M_X64 | ||||||
| 		callStack.AddrPC.Offset    = context.Eip; |         callStack.AddrPC.Offset    = context.Eip; | ||||||
| 		callStack.AddrStack.Offset = context.Esp; |         callStack.AddrStack.Offset = context.Esp; | ||||||
| 		callStack.AddrFrame.Offset = context.Ebp; |         callStack.AddrFrame.Offset = context.Ebp; | ||||||
| #else | #else | ||||||
| 		callStack.AddrPC.Offset    = context.Rip; |         callStack.AddrPC.Offset    = context.Rip; | ||||||
| 		callStack.AddrStack.Offset = context.Rsp; |         callStack.AddrStack.Offset = context.Rsp; | ||||||
| 		callStack.AddrFrame.Offset = context.Rbp; |         callStack.AddrFrame.Offset = context.Rbp; | ||||||
| #endif | #endif | ||||||
| 		callStack.AddrPC.Mode      = AddrModeFlat; |         callStack.AddrPC.Mode      = AddrModeFlat; | ||||||
| 		callStack.AddrStack.Mode   = AddrModeFlat; |         callStack.AddrStack.Mode   = AddrModeFlat; | ||||||
| 		callStack.AddrFrame.Mode   = AddrModeFlat; |         callStack.AddrFrame.Mode   = AddrModeFlat; | ||||||
| 
 | 
 | ||||||
| 		etfprint(file, "Call stack info: \n"); |         etfprint(file, "Call stack info: \n"); | ||||||
| 		etfprint(file, lpszMessage); |         etfprint(file, lpszMessage); | ||||||
| 
 | 
 | ||||||
| 		PrintFunctionAndSourceInfo(file, callStack); |         PrintFunctionAndSourceInfo(file, callStack); | ||||||
| 
 | 
 | ||||||
| 		for( ULONG index = 0; ; index++ )  |         for( ULONG index = 0; ; index++ )  | ||||||
| 		{ |         { | ||||||
| 			bResult = StackWalk( |             bResult = StackWalk( | ||||||
| 				IMAGE_FILE_MACHINE_I386, |                 IMAGE_FILE_MACHINE_I386, | ||||||
| 				hProcess, |                 hProcess, | ||||||
| 				hThread, |                 hThread, | ||||||
| 				&callStack, |                 &callStack, | ||||||
| 				NULL,  |                 NULL,  | ||||||
| 				NULL, |                 NULL, | ||||||
| 				SymFunctionTableAccess, |                 SymFunctionTableAccess, | ||||||
| 				SymGetModuleBase, |                 SymGetModuleBase, | ||||||
| 				NULL); |                 NULL); | ||||||
| 
 | 
 | ||||||
| 			if ( index == 0 ) |             if ( index == 0 ) | ||||||
| 				continue; |                 continue; | ||||||
| 
 | 
 | ||||||
| 			if( !bResult || callStack.AddrFrame.Offset == 0 )  |             if( !bResult || callStack.AddrFrame.Offset == 0 )  | ||||||
| 				break; |                 break; | ||||||
| 
 | 
 | ||||||
| 			PrintFunctionAndSourceInfo(file, callStack); |             PrintFunctionAndSourceInfo(file, callStack); | ||||||
| 
 | 
 | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		if ( hThread != GetCurrentThread() ) |         if ( hThread != GetCurrentThread() ) | ||||||
| 			ResumeThread( hThread ); |             ResumeThread( hThread ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void StackTrace(HANDLE hThread, const char* lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp ) | void StackTrace(HANDLE hThread, const char* lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp ) | ||||||
| { | { | ||||||
| 	STACKFRAME     callStack; |     STACKFRAME     callStack; | ||||||
| 	BOOL           bResult; |     BOOL           bResult; | ||||||
| 	TCHAR          symInfo[BUFFERSIZE] = _T("?"); |     TCHAR          symInfo[BUFFERSIZE] = _T("?"); | ||||||
| 	TCHAR          srcInfo[BUFFERSIZE] = _T("?"); |     TCHAR          srcInfo[BUFFERSIZE] = _T("?"); | ||||||
| 	HANDLE         hProcess = GetCurrentProcess(); |     HANDLE         hProcess = GetCurrentProcess(); | ||||||
| 
 | 
 | ||||||
| 	// If it's not this thread, let's suspend it, and resume it at the end
 |     // If it's not this thread, let's suspend it, and resume it at the end
 | ||||||
| 	if ( hThread != GetCurrentThread() ) |     if ( hThread != GetCurrentThread() ) | ||||||
| 		if ( SuspendThread( hThread ) == -1 ) |         if ( SuspendThread( hThread ) == -1 ) | ||||||
| 		{ |         { | ||||||
| 			// whaaat ?!
 |             // whaaat ?!
 | ||||||
| 			etfprint(file, "Call stack info failed\n"); |             etfprint(file, "Call stack info failed\n"); | ||||||
| 			return; |             return; | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		::ZeroMemory( &callStack, sizeof(callStack) ); |         ::ZeroMemory( &callStack, sizeof(callStack) ); | ||||||
| 		callStack.AddrPC.Offset    = eip; |         callStack.AddrPC.Offset    = eip; | ||||||
| 		callStack.AddrStack.Offset = esp; |         callStack.AddrStack.Offset = esp; | ||||||
| 		callStack.AddrFrame.Offset = ebp; |         callStack.AddrFrame.Offset = ebp; | ||||||
| 		callStack.AddrPC.Mode      = AddrModeFlat; |         callStack.AddrPC.Mode      = AddrModeFlat; | ||||||
| 		callStack.AddrStack.Mode   = AddrModeFlat; |         callStack.AddrStack.Mode   = AddrModeFlat; | ||||||
| 		callStack.AddrFrame.Mode   = AddrModeFlat; |         callStack.AddrFrame.Mode   = AddrModeFlat; | ||||||
| 
 | 
 | ||||||
| 		etfprint(file, "Call stack info: \n"); |         etfprint(file, "Call stack info: \n"); | ||||||
| 		etfprint(file, lpszMessage); |         etfprint(file, lpszMessage); | ||||||
| 
 | 
 | ||||||
| 		PrintFunctionAndSourceInfo(file, callStack); |         PrintFunctionAndSourceInfo(file, callStack); | ||||||
| 
 | 
 | ||||||
| 		for( ULONG index = 0; ; index++ )  |         for( ULONG index = 0; ; index++ )  | ||||||
| 		{ |         { | ||||||
| 			bResult = StackWalk( |             bResult = StackWalk( | ||||||
| 				IMAGE_FILE_MACHINE_I386, |                 IMAGE_FILE_MACHINE_I386, | ||||||
| 				hProcess, |                 hProcess, | ||||||
| 				hThread, |                 hThread, | ||||||
| 				&callStack, |                 &callStack, | ||||||
| 				NULL,  |                 NULL,  | ||||||
| 				NULL, |                 NULL, | ||||||
| 				SymFunctionTableAccess, |                 SymFunctionTableAccess, | ||||||
| 				SymGetModuleBase, |                 SymGetModuleBase, | ||||||
| 				NULL); |                 NULL); | ||||||
| 
 | 
 | ||||||
| 			if ( index == 0 ) |             if ( index == 0 ) | ||||||
| 				continue; |                 continue; | ||||||
| 
 | 
 | ||||||
| 			if( !bResult || callStack.AddrFrame.Offset == 0 )  |             if( !bResult || callStack.AddrFrame.Offset == 0 )  | ||||||
| 				break; |                 break; | ||||||
| 
 | 
 | ||||||
| 			PrintFunctionAndSourceInfo(file, callStack); |             PrintFunctionAndSourceInfo(file, callStack); | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		if ( hThread != GetCurrentThread() ) |         if ( hThread != GetCurrentThread() ) | ||||||
| 			ResumeThread( hThread ); |             ResumeThread( hThread ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| char g_uefbuf[2048]; | char g_uefbuf[2048]; | ||||||
| 
 | 
 | ||||||
| void etfprintf(FILE *file, const char *format, ...) | void etfprintf(FILE *file, const char *format, ...) | ||||||
| { | { | ||||||
| 	va_list ap; |     va_list ap; | ||||||
| 	va_start(ap, format); |     va_start(ap, format); | ||||||
| 	int len = vsprintf(g_uefbuf, format, ap); |     int len = vsprintf(g_uefbuf, format, ap); | ||||||
| 	fwrite(g_uefbuf, 1, len, file); |     fwrite(g_uefbuf, 1, len, file); | ||||||
| 	va_end(ap); |     va_end(ap); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void etfprint(FILE *file, const std::string &text) | void etfprint(FILE *file, const std::string &text) | ||||||
| { | { | ||||||
| 	size_t len = text.length(); |     size_t len = text.length(); | ||||||
| 	fwrite(text.data(), 1, len, file); |     fwrite(text.data(), 1, len, file); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif //WIN32
 | #endif //WIN32
 | ||||||
|  |  | ||||||
|  | @ -24,9 +24,9 @@ | ||||||
| 
 | 
 | ||||||
| #pragma comment( lib, "imagehlp.lib" ) | #pragma comment( lib, "imagehlp.lib" ) | ||||||
| 
 | 
 | ||||||
| #define EXTENDEDTRACEINITIALIZE( IniSymbolPath )	InitSymInfo( IniSymbolPath ) | #define EXTENDEDTRACEINITIALIZE( IniSymbolPath )    InitSymInfo( IniSymbolPath ) | ||||||
| #define EXTENDEDTRACEUNINITIALIZE()					UninitSymInfo() | #define EXTENDEDTRACEUNINITIALIZE()                    UninitSymInfo() | ||||||
| #define STACKTRACE(file)							StackTrace( GetCurrentThread(), "", file) | #define STACKTRACE(file)                            StackTrace( GetCurrentThread(), "", file) | ||||||
| #define STACKTRACE2(file, eip, esp, ebp) StackTrace(GetCurrentThread(), "", file, eip, esp, ebp) | #define STACKTRACE2(file, eip, esp, ebp) StackTrace(GetCurrentThread(), "", file, eip, esp, ebp) | ||||||
| // class File;
 | // class File;
 | ||||||
| 
 | 
 | ||||||
|  | @ -41,13 +41,13 @@ void etfprint(FILE *file, const std::string &text); | ||||||
| #define UEFBUFSIZE 2048 | #define UEFBUFSIZE 2048 | ||||||
| extern char g_uefbuf[UEFBUFSIZE]; | extern char g_uefbuf[UEFBUFSIZE]; | ||||||
| 
 | 
 | ||||||
| #else	// not WIN32
 | #else    // not WIN32
 | ||||||
| 
 | 
 | ||||||
| #define EXTENDEDTRACEINITIALIZE( IniSymbolPath )	((void)0) | #define EXTENDEDTRACEINITIALIZE( IniSymbolPath )    ((void)0) | ||||||
| #define EXTENDEDTRACEUNINITIALIZE()					((void)0) | #define EXTENDEDTRACEUNINITIALIZE()                    ((void)0) | ||||||
| #define STACKTRACE(file)							((void)0) | #define STACKTRACE(file)                            ((void)0) | ||||||
| #define STACKTRACE2(file, eip, esp, ebp)			((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 | class FifoQueue | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	FifoQueue() : m_size(0) |     FifoQueue() : m_size(0) | ||||||
| 	{ |     { | ||||||
| 		 m_write_ptr = m_read_ptr = new ElementPtr(); |          m_write_ptr = m_read_ptr = new ElementPtr(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	~FifoQueue() |     ~FifoQueue() | ||||||
| 	{ |     { | ||||||
| 		// this will empty out the whole queue
 |         // this will empty out the whole queue
 | ||||||
| 		delete m_read_ptr; |         delete m_read_ptr; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	u32 Size() const |     u32 Size() const | ||||||
| 	{ |     { | ||||||
| 		return m_size; |         return m_size; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	bool Empty() const |     bool Empty() const | ||||||
| 	{ |     { | ||||||
| 		//return (m_read_ptr == m_write_ptr);
 |         //return (m_read_ptr == m_write_ptr);
 | ||||||
| 		return (0 == m_size); |         return (0 == m_size); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	T& Front() const |     T& Front() const | ||||||
| 	{ |     { | ||||||
| 		return *m_read_ptr->current; |         return *m_read_ptr->current; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	template <typename Arg> |     template <typename Arg> | ||||||
| 	void Push(Arg&& t) |     void Push(Arg&& t) | ||||||
| 	{ |     { | ||||||
| 		// create the element, add it to the queue
 |         // create the element, add it to the queue
 | ||||||
| 		m_write_ptr->current = new T(std::forward<Arg>(t)); |         m_write_ptr->current = new T(std::forward<Arg>(t)); | ||||||
| 		// set the next pointer to a new element ptr
 |         // set the next pointer to a new element ptr
 | ||||||
| 		// then advance the write pointer 
 |         // then advance the write pointer 
 | ||||||
| 		m_write_ptr = m_write_ptr->next = new ElementPtr(); |         m_write_ptr = m_write_ptr->next = new ElementPtr(); | ||||||
| 		Common::AtomicIncrement(m_size); |         Common::AtomicIncrement(m_size); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void Pop() |     void Pop() | ||||||
| 	{ |     { | ||||||
| 		Common::AtomicDecrement(m_size); |         Common::AtomicDecrement(m_size); | ||||||
| 		ElementPtr *const tmpptr = m_read_ptr; |         ElementPtr *const tmpptr = m_read_ptr; | ||||||
| 		// advance the read pointer
 |         // advance the read pointer
 | ||||||
| 		m_read_ptr = m_read_ptr->next; |         m_read_ptr = m_read_ptr->next; | ||||||
| 		// set the next element to NULL to stop the recursive deletion
 |         // set the next element to NULL to stop the recursive deletion
 | ||||||
| 		tmpptr->next = NULL; |         tmpptr->next = NULL; | ||||||
| 		delete tmpptr;	// this also deletes the element
 |         delete tmpptr;    // this also deletes the element
 | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	bool Pop(T& t) |     bool Pop(T& t) | ||||||
| 	{ |     { | ||||||
| 		if (Empty()) |         if (Empty()) | ||||||
| 			return false; |             return false; | ||||||
| 
 | 
 | ||||||
| 		t = std::move(Front()); |         t = std::move(Front()); | ||||||
| 		Pop(); |         Pop(); | ||||||
| 
 | 
 | ||||||
| 		return true; |         return true; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// not thread-safe
 |     // not thread-safe
 | ||||||
| 	void Clear() |     void Clear() | ||||||
| 	{ |     { | ||||||
| 		m_size = 0; |         m_size = 0; | ||||||
| 		delete m_read_ptr; |         delete m_read_ptr; | ||||||
| 		m_write_ptr = m_read_ptr = new ElementPtr(); |         m_write_ptr = m_read_ptr = new ElementPtr(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	// stores a pointer to element
 |     // stores a pointer to element
 | ||||||
| 	// and a pointer to the next ElementPtr
 |     // and a pointer to the next ElementPtr
 | ||||||
| 	class ElementPtr |     class ElementPtr | ||||||
| 	{ |     { | ||||||
| 	public: |     public: | ||||||
| 		ElementPtr() : current(NULL), next(NULL) {} |         ElementPtr() : current(NULL), next(NULL) {} | ||||||
| 
 | 
 | ||||||
| 		~ElementPtr() |         ~ElementPtr() | ||||||
| 		{ |         { | ||||||
| 			if (current) |             if (current) | ||||||
| 			{ |             { | ||||||
| 				delete current; |                 delete current; | ||||||
| 				// recusion ftw
 |                 // recusion ftw
 | ||||||
| 				if (next) |                 if (next) | ||||||
| 					delete next; |                     delete next; | ||||||
| 			} |             } | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		T *volatile current; |         T *volatile current; | ||||||
| 		ElementPtr *volatile next; |         ElementPtr *volatile next; | ||||||
| 	}; |     }; | ||||||
| 
 | 
 | ||||||
| 	ElementPtr *volatile m_write_ptr; |     ElementPtr *volatile m_write_ptr; | ||||||
| 	ElementPtr *volatile m_read_ptr; |     ElementPtr *volatile m_read_ptr; | ||||||
| 	volatile u32 m_size; |     volatile u32 m_size; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,85 +22,85 @@ | ||||||
| 
 | 
 | ||||||
| CFileSearch::CFileSearch(const CFileSearch::XStringVector& _rSearchStrings, const CFileSearch::XStringVector& _rDirectories) | CFileSearch::CFileSearch(const CFileSearch::XStringVector& _rSearchStrings, const CFileSearch::XStringVector& _rDirectories) | ||||||
| { | { | ||||||
| 	// Reverse the loop order for speed?
 |     // Reverse the loop order for speed?
 | ||||||
| 	for (size_t j = 0; j < _rSearchStrings.size(); j++) |     for (size_t j = 0; j < _rSearchStrings.size(); j++) | ||||||
| 	{ |     { | ||||||
| 		for (size_t i = 0; i < _rDirectories.size(); i++) |         for (size_t i = 0; i < _rDirectories.size(); i++) | ||||||
| 		{ |         { | ||||||
| 			FindFiles(_rSearchStrings[j], _rDirectories[i]); |             FindFiles(_rSearchStrings[j], _rDirectories[i]); | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void CFileSearch::FindFiles(const std::string& _searchString, const std::string& _strPath) | void CFileSearch::FindFiles(const std::string& _searchString, const std::string& _strPath) | ||||||
| { | { | ||||||
| 	std::string GCMSearchPath; |     std::string GCMSearchPath; | ||||||
| 	BuildCompleteFilename(GCMSearchPath, _strPath, _searchString); |     BuildCompleteFilename(GCMSearchPath, _strPath, _searchString); | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	WIN32_FIND_DATA findData; |     WIN32_FIND_DATA findData; | ||||||
| 	HANDLE FindFirst = FindFirstFile(UTF8ToTStr(GCMSearchPath).c_str(), &findData); |     HANDLE FindFirst = FindFirstFile(UTF8ToTStr(GCMSearchPath).c_str(), &findData); | ||||||
| 
 | 
 | ||||||
| 	if (FindFirst != INVALID_HANDLE_VALUE) |     if (FindFirst != INVALID_HANDLE_VALUE) | ||||||
| 	{ |     { | ||||||
| 		bool bkeepLooping = true; |         bool bkeepLooping = true; | ||||||
| 
 | 
 | ||||||
| 		while (bkeepLooping) |         while (bkeepLooping) | ||||||
| 		{			 |         {             | ||||||
| 			if (findData.cFileName[0] != '.') |             if (findData.cFileName[0] != '.') | ||||||
| 			{ |             { | ||||||
| 				std::string strFilename; |                 std::string strFilename; | ||||||
| 				BuildCompleteFilename(strFilename, _strPath, TStrToUTF8(findData.cFileName)); |                 BuildCompleteFilename(strFilename, _strPath, TStrToUTF8(findData.cFileName)); | ||||||
| 				m_FileNames.push_back(strFilename); |                 m_FileNames.push_back(strFilename); | ||||||
| 			} |             } | ||||||
| 
 | 
 | ||||||
| 			bkeepLooping = FindNextFile(FindFirst, &findData) ? true : false; |             bkeepLooping = FindNextFile(FindFirst, &findData) ? true : false; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| 	FindClose(FindFirst); |     FindClose(FindFirst); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #else | #else | ||||||
| 	// TODO: super lame/broken
 |     // TODO: super lame/broken
 | ||||||
| 
 | 
 | ||||||
| 	auto end_match(_searchString); |     auto end_match(_searchString); | ||||||
| 
 | 
 | ||||||
| 	// assuming we have a "*.blah"-like pattern
 |     // assuming we have a "*.blah"-like pattern
 | ||||||
| 	if (!end_match.empty() && end_match[0] == '*') |     if (!end_match.empty() && end_match[0] == '*') | ||||||
| 		end_match.erase(0, 1); |         end_match.erase(0, 1); | ||||||
| 
 | 
 | ||||||
| 	// ugly
 |     // ugly
 | ||||||
| 	if (end_match == ".*") |     if (end_match == ".*") | ||||||
| 		end_match.clear(); |         end_match.clear(); | ||||||
| 
 | 
 | ||||||
| 	DIR* dir = opendir(_strPath.c_str()); |     DIR* dir = opendir(_strPath.c_str()); | ||||||
| 
 | 
 | ||||||
| 	if (!dir) |     if (!dir) | ||||||
| 		return; |         return; | ||||||
| 
 | 
 | ||||||
| 	while (auto const dp = readdir(dir)) |     while (auto const dp = readdir(dir)) | ||||||
| 	{ |     { | ||||||
| 		std::string found(dp->d_name); |         std::string found(dp->d_name); | ||||||
| 
 | 
 | ||||||
| 		if ((found != ".") && (found != "..") |         if ((found != ".") && (found != "..") | ||||||
| 			&& (found.size() >= end_match.size()) |             && (found.size() >= end_match.size()) | ||||||
| 			&& std::equal(end_match.rbegin(), end_match.rend(), found.rbegin())) |             && std::equal(end_match.rbegin(), end_match.rend(), found.rbegin())) | ||||||
| 		{ |         { | ||||||
| 			std::string full_name; |             std::string full_name; | ||||||
| 			if (_strPath.c_str()[_strPath.size()-1] == DIR_SEP_CHR) |             if (_strPath.c_str()[_strPath.size()-1] == DIR_SEP_CHR) | ||||||
| 				full_name = _strPath + found; |                 full_name = _strPath + found; | ||||||
| 			else |             else | ||||||
| 				full_name = _strPath + DIR_SEP + found; |                 full_name = _strPath + DIR_SEP + found; | ||||||
| 
 | 
 | ||||||
| 			m_FileNames.push_back(full_name); |             m_FileNames.push_back(full_name); | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	closedir(dir); |     closedir(dir); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const CFileSearch::XStringVector& CFileSearch::GetFileNames() const | const CFileSearch::XStringVector& CFileSearch::GetFileNames() const | ||||||
| { | { | ||||||
| 	return m_FileNames; |     return m_FileNames; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -12,16 +12,16 @@ | ||||||
| class CFileSearch | class CFileSearch | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	typedef std::vector<std::string>XStringVector; |     typedef std::vector<std::string>XStringVector; | ||||||
| 
 | 
 | ||||||
| 	CFileSearch(const XStringVector& _rSearchStrings, const XStringVector& _rDirectories); |     CFileSearch(const XStringVector& _rSearchStrings, const XStringVector& _rDirectories); | ||||||
| 	const XStringVector& GetFileNames() const; |     const XStringVector& GetFileNames() const; | ||||||
| 
 | 
 | ||||||
| private: | 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_
 | #endif // _FILESEARCH_H_
 | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -16,59 +16,59 @@ | ||||||
| template <class T, int N> | template <class T, int N> | ||||||
| class fixed_size_queue.h | class fixed_size_queue.h | ||||||
| { | { | ||||||
| 	T *storage; |     T *storage; | ||||||
| 	int head; |     int head; | ||||||
| 	int tail; |     int tail; | ||||||
| 	int count;  // sacrifice 4 bytes for a simpler implementation. may optimize away in the future.
 |     int count;  // sacrifice 4 bytes for a simpler implementation. may optimize away in the future.
 | ||||||
| 
 | 
 | ||||||
| 	// Make copy constructor private for now.
 |     // Make copy constructor private for now.
 | ||||||
| 	fixed_size_queue.h(fixed_size_queue.h &other) {	} |     fixed_size_queue.h(fixed_size_queue.h &other) {    } | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
| 	fixed_size_queue.h() |     fixed_size_queue.h() | ||||||
| 	{ |     { | ||||||
| 		storage = new T[N]; |         storage = new T[N]; | ||||||
| 		clear(); |         clear(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	~fixed_size_queue.h() |     ~fixed_size_queue.h() | ||||||
| 	{ |     { | ||||||
| 		delete [] storage; |         delete [] storage; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void clear() { |     void clear() { | ||||||
| 		head = 0; |         head = 0; | ||||||
| 		tail = 0; |         tail = 0; | ||||||
| 		count = 0; |         count = 0; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void push(T t) { |     void push(T t) { | ||||||
| 		storage[tail] = t; |         storage[tail] = t; | ||||||
| 		tail++; |         tail++; | ||||||
| 		if (tail == N) |         if (tail == N) | ||||||
| 			tail = 0; |             tail = 0; | ||||||
| 		count++; |         count++; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void pop() { |     void pop() { | ||||||
| 		head++; |         head++; | ||||||
| 		if (head == N) |         if (head == N) | ||||||
| 			head = 0; |             head = 0; | ||||||
| 		count--; |         count--; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	T pop_front() { |     T pop_front() { | ||||||
| 		const T &temp = storage[head]; |         const T &temp = storage[head]; | ||||||
| 		pop(); |         pop(); | ||||||
| 		return temp; |         return temp; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	T &front() { return storage[head]; } |     T &front() { return storage[head]; } | ||||||
| 	const T &front() const { return storage[head]; } |     const T &front() const { return storage[head]; } | ||||||
| 
 | 
 | ||||||
| 	size_t size() const { |     size_t size() const { | ||||||
| 		return count; |         return count; | ||||||
| 	} |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // _FIXED_SIZE_QUEUE_H_
 | #endif // _FIXED_SIZE_QUEUE_H_
 | ||||||
|  |  | ||||||
|  | @ -16,29 +16,29 @@ static u64 (*ptrHashFunction)(const u8 *src, int len, u32 samples) = &GetMurmurH | ||||||
| // Implementation from Wikipedia.
 | // Implementation from Wikipedia.
 | ||||||
| u32 HashFletcher(const u8* data_u8, size_t length) | u32 HashFletcher(const u8* data_u8, size_t length) | ||||||
| { | { | ||||||
| 	const u16* data = (const u16*)data_u8; /* Pointer to the data to be summed */ |     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 */ |     size_t len = (length + 1) / 2; /* Length in 16-bit words */ | ||||||
| 	u32 sum1 = 0xffff, sum2 = 0xffff; |     u32 sum1 = 0xffff, sum2 = 0xffff; | ||||||
| 
 | 
 | ||||||
| 	while (len) |     while (len) | ||||||
| 	{ |     { | ||||||
| 		size_t tlen = len > 360 ? 360 : len; |         size_t tlen = len > 360 ? 360 : len; | ||||||
| 		len -= tlen; |         len -= tlen; | ||||||
| 
 | 
 | ||||||
| 		do { |         do { | ||||||
| 			sum1 += *data++; |             sum1 += *data++; | ||||||
| 			sum2 += sum1; |             sum2 += sum1; | ||||||
| 		} |         } | ||||||
| 		while (--tlen); |         while (--tlen); | ||||||
| 
 | 
 | ||||||
| 		sum1 = (sum1 & 0xffff) + (sum1 >> 16); |         sum1 = (sum1 & 0xffff) + (sum1 >> 16); | ||||||
| 		sum2 = (sum2 & 0xffff) + (sum2 >> 16); |         sum2 = (sum2 & 0xffff) + (sum2 >> 16); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// Second reduction step to reduce sums to 16 bits
 |     // Second reduction step to reduce sums to 16 bits
 | ||||||
| 	sum1 = (sum1 & 0xffff) + (sum1 >> 16); |     sum1 = (sum1 & 0xffff) + (sum1 >> 16); | ||||||
| 	sum2 = (sum2 & 0xffff) + (sum2 >> 16); |     sum2 = (sum2 & 0xffff) + (sum2 >> 16); | ||||||
| 	return(sum2 << 16 | sum1); |     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
 | // data: Pointer to the data to be summed; len is in bytes
 | ||||||
| u32 HashAdler32(const u8* data, size_t len) | u32 HashAdler32(const u8* data, size_t len) | ||||||
| { | { | ||||||
| 	u32 a = 1, b = 0; |     u32 a = 1, b = 0; | ||||||
| 
 | 
 | ||||||
| 	while (len) |     while (len) | ||||||
| 	{ |     { | ||||||
| 		size_t tlen = len > 5550 ? 5550 : len; |         size_t tlen = len > 5550 ? 5550 : len; | ||||||
| 		len -= tlen; |         len -= tlen; | ||||||
| 
 | 
 | ||||||
| 		do |         do | ||||||
| 		{ |         { | ||||||
| 			a += *data++; |             a += *data++; | ||||||
| 			b += a; |             b += a; | ||||||
| 		} |         } | ||||||
| 		while (--tlen); |         while (--tlen); | ||||||
| 
 | 
 | ||||||
| 		a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER); |         a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER); | ||||||
| 		b = (b & 0xffff) + (b >> 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.
 |     // It can be shown that a <= 0x1013a here, so a single subtract will do.
 | ||||||
| 	if (a >= MOD_ADLER) |     if (a >= MOD_ADLER) | ||||||
| 	{ |     { | ||||||
| 		a -= MOD_ADLER; |         a -= MOD_ADLER; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// It can be shown that b can reach 0xfff87 here.
 |     // It can be shown that b can reach 0xfff87 here.
 | ||||||
| 	b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); |     b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); | ||||||
| 
 | 
 | ||||||
| 	if (b >= MOD_ADLER) |     if (b >= MOD_ADLER) | ||||||
| 	{ |     { | ||||||
| 		b -= MOD_ADLER; |         b -= MOD_ADLER; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	return((b << 16) | a); |     return((b << 16) | a); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Stupid hash - but can't go back now :)
 | // Stupid hash - but can't go back now :)
 | ||||||
| // Don't use for new things. At least it's reasonably fast.
 | // Don't use for new things. At least it's reasonably fast.
 | ||||||
| u32 HashEctor(const u8* ptr, int length) | u32 HashEctor(const u8* ptr, int length) | ||||||
| { | { | ||||||
| 	u32 crc = 0; |     u32 crc = 0; | ||||||
| 
 | 
 | ||||||
| 	for (int i = 0; i < length; i++) |     for (int i = 0; i < length; i++) | ||||||
| 	{ |     { | ||||||
| 		crc ^= ptr[i]; |         crc ^= ptr[i]; | ||||||
| 		crc = (crc << 3) | (crc >> 29); |         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) | 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) | inline void bmix64(u64 & h1, u64 & h2, u64 & k1, u64 & k2, u64 & c1, u64 & c2) | ||||||
| { | { | ||||||
| 	k1 *= c1;  |     k1 *= c1;  | ||||||
| 	k1  = _rotl64(k1,23);  |     k1  = _rotl64(k1,23);  | ||||||
| 	k1 *= c2; |     k1 *= c2; | ||||||
| 	h1 ^= k1; |     h1 ^= k1; | ||||||
| 	h1 += h2; |     h1 += h2; | ||||||
| 
 | 
 | ||||||
| 	h2 = _rotl64(h2,41); |     h2 = _rotl64(h2,41); | ||||||
| 
 | 
 | ||||||
| 	k2 *= c2;  |     k2 *= c2;  | ||||||
| 	k2  = _rotl64(k2,23); |     k2  = _rotl64(k2,23); | ||||||
| 	k2 *= c1; |     k2 *= c1; | ||||||
| 	h2 ^= k2; |     h2 ^= k2; | ||||||
| 	h2 += h1; |     h2 += h1; | ||||||
| 
 | 
 | ||||||
| 	h1 = h1*3+0x52dce729; |     h1 = h1*3+0x52dce729; | ||||||
| 	h2 = h2*3+0x38495ab5; |     h2 = h2*3+0x38495ab5; | ||||||
| 
 | 
 | ||||||
| 	c1 = c1*5+0x7b7d159c; |     c1 = c1*5+0x7b7d159c; | ||||||
| 	c2 = c2*5+0x6bce6396; |     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) | inline u64 fmix64(u64 k) | ||||||
| { | { | ||||||
| 	k ^= k >> 33; |     k ^= k >> 33; | ||||||
| 	k *= 0xff51afd7ed558ccd; |     k *= 0xff51afd7ed558ccd; | ||||||
| 	k ^= k >> 33; |     k ^= k >> 33; | ||||||
| 	k *= 0xc4ceb9fe1a85ec53; |     k *= 0xc4ceb9fe1a85ec53; | ||||||
| 	k ^= k >> 33; |     k ^= k >> 33; | ||||||
| 
 | 
 | ||||||
| 	return k; |     return k; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u64 GetMurmurHash3(const u8 *src, int len, u32 samples) | u64 GetMurmurHash3(const u8 *src, int len, u32 samples) | ||||||
| { | { | ||||||
| 	const u8 * data = (const u8*)src; |     const u8 * data = (const u8*)src; | ||||||
| 	const int nblocks = len / 16; |     const int nblocks = len / 16; | ||||||
| 	u32 Step = (len / 8); |     u32 Step = (len / 8); | ||||||
| 	if(samples == 0) samples = max(Step, 1u); |     if(samples == 0) samples = max(Step, 1u); | ||||||
| 	Step = Step / samples; |     Step = Step / samples; | ||||||
| 	if(Step < 1) Step = 1; |     if(Step < 1) Step = 1; | ||||||
| 
 | 
 | ||||||
| 	u64 h1 = 0x9368e53c2f6af274; |     u64 h1 = 0x9368e53c2f6af274; | ||||||
| 	u64 h2 = 0x586dcd208f7cd3fd; |     u64 h2 = 0x586dcd208f7cd3fd; | ||||||
| 
 | 
 | ||||||
| 	u64 c1 = 0x87c37b91114253d5; |     u64 c1 = 0x87c37b91114253d5; | ||||||
| 	u64 c2 = 0x4cf5ad432745937f; |     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) |     for(int i = 0; i < nblocks; i+=Step) | ||||||
| 	{ |     { | ||||||
| 		u64 k1 = getblock(blocks,i*2+0); |         u64 k1 = getblock(blocks,i*2+0); | ||||||
| 		u64 k2 = getblock(blocks,i*2+1); |         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 k1 = 0; | ||||||
| 	u64 k2 = 0; |     u64 k2 = 0; | ||||||
| 
 | 
 | ||||||
| 	switch(len & 15) |     switch(len & 15) | ||||||
| 	{ |     { | ||||||
| 	case 15: k2 ^= u64(tail[14]) << 48; |     case 15: k2 ^= u64(tail[14]) << 48; | ||||||
| 	case 14: k2 ^= u64(tail[13]) << 40; |     case 14: k2 ^= u64(tail[13]) << 40; | ||||||
| 	case 13: k2 ^= u64(tail[12]) << 32; |     case 13: k2 ^= u64(tail[12]) << 32; | ||||||
| 	case 12: k2 ^= u64(tail[11]) << 24; |     case 12: k2 ^= u64(tail[11]) << 24; | ||||||
| 	case 11: k2 ^= u64(tail[10]) << 16; |     case 11: k2 ^= u64(tail[10]) << 16; | ||||||
| 	case 10: k2 ^= u64(tail[ 9]) << 8; |     case 10: k2 ^= u64(tail[ 9]) << 8; | ||||||
| 	case  9: k2 ^= u64(tail[ 8]) << 0; |     case  9: k2 ^= u64(tail[ 8]) << 0; | ||||||
| 
 | 
 | ||||||
| 	case  8: k1 ^= u64(tail[ 7]) << 56; |     case  8: k1 ^= u64(tail[ 7]) << 56; | ||||||
| 	case  7: k1 ^= u64(tail[ 6]) << 48; |     case  7: k1 ^= u64(tail[ 6]) << 48; | ||||||
| 	case  6: k1 ^= u64(tail[ 5]) << 40; |     case  6: k1 ^= u64(tail[ 5]) << 40; | ||||||
| 	case  5: k1 ^= u64(tail[ 4]) << 32; |     case  5: k1 ^= u64(tail[ 4]) << 32; | ||||||
| 	case  4: k1 ^= u64(tail[ 3]) << 24; |     case  4: k1 ^= u64(tail[ 3]) << 24; | ||||||
| 	case  3: k1 ^= u64(tail[ 2]) << 16; |     case  3: k1 ^= u64(tail[ 2]) << 16; | ||||||
| 	case  2: k1 ^= u64(tail[ 1]) << 8; |     case  2: k1 ^= u64(tail[ 1]) << 8; | ||||||
| 	case  1: k1 ^= u64(tail[ 0]) << 0; |     case  1: k1 ^= u64(tail[ 0]) << 0; | ||||||
| 			bmix64(h1,h2,k1,k2,c1,c2); |             bmix64(h1,h2,k1,k2,c1,c2); | ||||||
| 	}; |     }; | ||||||
| 
 | 
 | ||||||
| 	//----------
 |     //----------
 | ||||||
| 	// finalization
 |     // finalization
 | ||||||
| 
 | 
 | ||||||
| 	h2 ^= len; |     h2 ^= len; | ||||||
| 
 | 
 | ||||||
| 	h1 += h2; |     h1 += h2; | ||||||
| 	h2 += h1; |     h2 += h1; | ||||||
| 
 | 
 | ||||||
| 	h1 = fmix64(h1); |     h1 = fmix64(h1); | ||||||
| 	h2 = fmix64(h2); |     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) | u64 GetCRC32(const u8 *src, int len, u32 samples) | ||||||
| { | { | ||||||
| #if _M_SSE >= 0x402 | #if _M_SSE >= 0x402 | ||||||
| 	u64 h = len; |     u64 h = len; | ||||||
| 	u32 Step = (len / 8); |     u32 Step = (len / 8); | ||||||
| 	const u64 *data = (const u64 *)src; |     const u64 *data = (const u64 *)src; | ||||||
| 	const u64 *end = data + Step; |     const u64 *end = data + Step; | ||||||
| 	if(samples == 0) samples = max(Step, 1u); |     if(samples == 0) samples = max(Step, 1u); | ||||||
| 	Step = Step / samples; |     Step = Step / samples; | ||||||
| 	if(Step < 1) Step = 1; |     if(Step < 1) Step = 1; | ||||||
| 	while(data < end) |     while(data < end) | ||||||
| 	{ |     { | ||||||
| 		h = _mm_crc32_u64(h, data[0]); |         h = _mm_crc32_u64(h, data[0]); | ||||||
| 		data += Step; |         data += Step; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	const u8 *data2 = (const u8*)end; |     const u8 *data2 = (const u8*)end; | ||||||
| 	return _mm_crc32_u64(h, u64(data2[0])); |     return _mm_crc32_u64(h, u64(data2[0])); | ||||||
| #else | #else | ||||||
| 	return 0; |     return 0; | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -259,68 +259,68 @@ u64 GetCRC32(const u8 *src, int len, u32 samples) | ||||||
|  */ |  */ | ||||||
| u64 GetHashHiresTexture(const u8 *src, int len, u32 samples) | u64 GetHashHiresTexture(const u8 *src, int len, u32 samples) | ||||||
| { | { | ||||||
| 	const u64 m = 0xc6a4a7935bd1e995; |     const u64 m = 0xc6a4a7935bd1e995; | ||||||
| 	u64 h = len * m; |     u64 h = len * m; | ||||||
| 	const int r = 47; |     const int r = 47; | ||||||
| 	u32 Step = (len / 8); |     u32 Step = (len / 8); | ||||||
| 	const u64 *data = (const u64 *)src; |     const u64 *data = (const u64 *)src; | ||||||
| 	const u64 *end = data + Step; |     const u64 *end = data + Step; | ||||||
| 	if(samples == 0) samples = max(Step, 1u); |     if(samples == 0) samples = max(Step, 1u); | ||||||
| 	Step = Step / samples; |     Step = Step / samples; | ||||||
| 	if(Step < 1) Step = 1; |     if(Step < 1) Step = 1; | ||||||
| 	while(data < end) |     while(data < end) | ||||||
| 	{ |     { | ||||||
| 		u64 k = data[0]; |         u64 k = data[0]; | ||||||
| 		data+=Step; |         data+=Step; | ||||||
| 		k *= m; |         k *= m; | ||||||
| 		k ^= k >> r;  |         k ^= k >> r;  | ||||||
| 		k *= m; |         k *= m; | ||||||
| 		h ^= k; |         h ^= k; | ||||||
| 		h *= m; |         h *= m; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	const u8 * data2 = (const u8*)end; |     const u8 * data2 = (const u8*)end; | ||||||
| 
 | 
 | ||||||
| 	switch(len & 7) |     switch(len & 7) | ||||||
| 	{ |     { | ||||||
| 	case 7: h ^= u64(data2[6]) << 48; |     case 7: h ^= u64(data2[6]) << 48; | ||||||
| 	case 6: h ^= u64(data2[5]) << 40; |     case 6: h ^= u64(data2[5]) << 40; | ||||||
| 	case 5: h ^= u64(data2[4]) << 32; |     case 5: h ^= u64(data2[4]) << 32; | ||||||
| 	case 4: h ^= u64(data2[3]) << 24; |     case 4: h ^= u64(data2[3]) << 24; | ||||||
| 	case 3: h ^= u64(data2[2]) << 16; |     case 3: h ^= u64(data2[2]) << 16; | ||||||
| 	case 2: h ^= u64(data2[1]) << 8; |     case 2: h ^= u64(data2[1]) << 8; | ||||||
| 	case 1: h ^= u64(data2[0]); |     case 1: h ^= u64(data2[0]); | ||||||
| 			h *= m; |             h *= m; | ||||||
| 	}; |     }; | ||||||
|   |   | ||||||
| 	h ^= h >> r; |     h ^= h >> r; | ||||||
| 	h *= m; |     h *= m; | ||||||
| 	h ^= h >> r; |     h ^= h >> r; | ||||||
| 
 | 
 | ||||||
| 	return h; |     return h; | ||||||
| }  | }  | ||||||
| #else | #else | ||||||
| // CRC32 hash using the SSE4.2 instruction
 | // CRC32 hash using the SSE4.2 instruction
 | ||||||
| u64 GetCRC32(const u8 *src, int len, u32 samples) | u64 GetCRC32(const u8 *src, int len, u32 samples) | ||||||
| { | { | ||||||
| #if _M_SSE >= 0x402 | #if _M_SSE >= 0x402 | ||||||
| 	u32 h = len; |     u32 h = len; | ||||||
| 	u32 Step = (len/4); |     u32 Step = (len/4); | ||||||
| 	const u32 *data = (const u32 *)src; |     const u32 *data = (const u32 *)src; | ||||||
| 	const u32 *end = data + Step; |     const u32 *end = data + Step; | ||||||
| 	if(samples == 0) samples = max(Step, 1u); |     if(samples == 0) samples = max(Step, 1u); | ||||||
| 	Step  = Step / samples; |     Step  = Step / samples; | ||||||
| 	if(Step < 1) Step = 1; |     if(Step < 1) Step = 1; | ||||||
| 	while(data < end) |     while(data < end) | ||||||
| 	{ |     { | ||||||
| 		h = _mm_crc32_u32(h, data[0]); |         h = _mm_crc32_u32(h, data[0]); | ||||||
| 		data += Step; |         data += Step; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	const u8 *data2 = (const u8*)end; |     const u8 *data2 = (const u8*)end; | ||||||
| 	return (u64)_mm_crc32_u32(h, u32(data2[0])); |     return (u64)_mm_crc32_u32(h, u32(data2[0])); | ||||||
| #else | #else | ||||||
| 	return 0; |     return 0; | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -330,7 +330,7 @@ u64 GetCRC32(const u8 *src, int len, u32 samples) | ||||||
| 
 | 
 | ||||||
| inline u32 getblock(const u32 * p, int i) | 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) | inline u32 fmix32(u32 h) | ||||||
| { | { | ||||||
| 	h ^= h >> 16; |     h ^= h >> 16; | ||||||
| 	h *= 0x85ebca6b; |     h *= 0x85ebca6b; | ||||||
| 	h ^= h >> 13; |     h ^= h >> 13; | ||||||
| 	h *= 0xc2b2ae35; |     h *= 0xc2b2ae35; | ||||||
| 	h ^= h >> 16; |     h ^= h >> 16; | ||||||
| 
 | 
 | ||||||
| 	return h; |     return h; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline void bmix32(u32 & h1, u32 & h2, u32 & k1, u32 & k2, u32 & c1, u32 & c2) | inline void bmix32(u32 & h1, u32 & h2, u32 & k1, u32 & k2, u32 & c1, u32 & c2) | ||||||
| { | { | ||||||
| 	k1 *= c1;  |     k1 *= c1;  | ||||||
| 	k1  = _rotl(k1,11);  |     k1  = _rotl(k1,11);  | ||||||
| 	k1 *= c2; |     k1 *= c2; | ||||||
| 	h1 ^= k1; |     h1 ^= k1; | ||||||
| 	h1 += h2; |     h1 += h2; | ||||||
| 
 | 
 | ||||||
| 	h2 = _rotl(h2,17); |     h2 = _rotl(h2,17); | ||||||
| 
 | 
 | ||||||
| 	k2 *= c2;  |     k2 *= c2;  | ||||||
| 	k2  = _rotl(k2,11); |     k2  = _rotl(k2,11); | ||||||
| 	k2 *= c1; |     k2 *= c1; | ||||||
| 	h2 ^= k2; |     h2 ^= k2; | ||||||
| 	h2 += h1; |     h2 += h1; | ||||||
| 
 | 
 | ||||||
| 	h1 = h1*3+0x52dce729; |     h1 = h1*3+0x52dce729; | ||||||
| 	h2 = h2*3+0x38495ab5; |     h2 = h2*3+0x38495ab5; | ||||||
| 
 | 
 | ||||||
| 	c1 = c1*5+0x7b7d159c; |     c1 = c1*5+0x7b7d159c; | ||||||
| 	c2 = c2*5+0x6bce6396; |     c2 = c2*5+0x6bce6396; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| //----------
 | //----------
 | ||||||
| 
 | 
 | ||||||
| u64 GetMurmurHash3(const u8* src, int len, u32 samples) | u64 GetMurmurHash3(const u8* src, int len, u32 samples) | ||||||
| { | { | ||||||
| 	const u8 * data = (const u8*)src; |     const u8 * data = (const u8*)src; | ||||||
| 	u32 out[2]; |     u32 out[2]; | ||||||
| 	const int nblocks = len / 8; |     const int nblocks = len / 8; | ||||||
| 	u32 Step = (len / 4); |     u32 Step = (len / 4); | ||||||
| 	if(samples == 0) samples = max(Step, 1u); |     if(samples == 0) samples = max(Step, 1u); | ||||||
| 	Step = Step / samples; |     Step = Step / samples; | ||||||
| 	if(Step < 1) Step = 1; |     if(Step < 1) Step = 1; | ||||||
| 
 | 
 | ||||||
| 	u32 h1 = 0x8de1c3ac; |     u32 h1 = 0x8de1c3ac; | ||||||
| 	u32 h2 = 0xbab98226; |     u32 h2 = 0xbab98226; | ||||||
| 
 | 
 | ||||||
| 	u32 c1 = 0x95543787; |     u32 c1 = 0x95543787; | ||||||
| 	u32 c2 = 0x2ad7eb25; |     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) |     for(int i = -nblocks; i < 0; i+=Step) | ||||||
| 	{ |     { | ||||||
| 		u32 k1 = getblock(blocks,i*2+0); |         u32 k1 = getblock(blocks,i*2+0); | ||||||
| 		u32 k2 = getblock(blocks,i*2+1); |         u32 k2 = getblock(blocks,i*2+1); | ||||||
| 
 | 
 | ||||||
| 		bmix32(h1,h2,k1,k2,c1,c2); |         bmix32(h1,h2,k1,k2,c1,c2); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	//----------
 |     //----------
 | ||||||
| 	// tail
 |     // tail
 | ||||||
|      |      | ||||||
| 	const u8 * tail = (const u8*)(data + nblocks*8); |     const u8 * tail = (const u8*)(data + nblocks*8); | ||||||
| 
 | 
 | ||||||
| 	u32 k1 = 0; |     u32 k1 = 0; | ||||||
| 	u32 k2 = 0; |     u32 k2 = 0; | ||||||
| 
 | 
 | ||||||
| 	switch(len & 7) |     switch(len & 7) | ||||||
| 	{ |     { | ||||||
| 	case 7: k2 ^= tail[6] << 16; |     case 7: k2 ^= tail[6] << 16; | ||||||
| 	case 6: k2 ^= tail[5] << 8; |     case 6: k2 ^= tail[5] << 8; | ||||||
| 	case 5: k2 ^= tail[4] << 0; |     case 5: k2 ^= tail[4] << 0; | ||||||
| 	case 4: k1 ^= tail[3] << 24; |     case 4: k1 ^= tail[3] << 24; | ||||||
| 	case 3: k1 ^= tail[2] << 16; |     case 3: k1 ^= tail[2] << 16; | ||||||
| 	case 2: k1 ^= tail[1] << 8; |     case 2: k1 ^= tail[1] << 8; | ||||||
| 	case 1: k1 ^= tail[0] << 0; |     case 1: k1 ^= tail[0] << 0; | ||||||
| 	        bmix32(h1,h2,k1,k2,c1,c2); |             bmix32(h1,h2,k1,k2,c1,c2); | ||||||
| 	}; |     }; | ||||||
| 
 | 
 | ||||||
| 	//----------
 |     //----------
 | ||||||
| 	// finalization
 |     // finalization
 | ||||||
| 
 | 
 | ||||||
| 	h2 ^= len; |     h2 ^= len; | ||||||
| 
 | 
 | ||||||
| 	h1 += h2; |     h1 += h2; | ||||||
| 	h2 += h1; |     h2 += h1; | ||||||
| 
 | 
 | ||||||
| 	h1 = fmix32(h1); |     h1 = fmix32(h1); | ||||||
| 	h2 = fmix32(h2); |     h2 = fmix32(h2); | ||||||
| 
 | 
 | ||||||
| 	h1 += h2; |     h1 += h2; | ||||||
| 	h2 += h1; |     h2 += h1; | ||||||
| 
 | 
 | ||||||
| 	out[0] = h1; |     out[0] = h1; | ||||||
| 	out[1] = h2; |     out[1] = h2; | ||||||
|      |      | ||||||
| 	return *((u64 *)&out); |     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) | u64 GetHashHiresTexture(const u8 *src, int len, u32 samples) | ||||||
| { | { | ||||||
| 	const u64 m = 0xc6a4a7935bd1e995ULL; |     const u64 m = 0xc6a4a7935bd1e995ULL; | ||||||
| 	u64 h = len * m; |     u64 h = len * m; | ||||||
| 	const int r = 47; |     const int r = 47; | ||||||
| 	u32 Step = (len / 8); |     u32 Step = (len / 8); | ||||||
| 	const u64 *data = (const u64 *)src; |     const u64 *data = (const u64 *)src; | ||||||
| 	const u64 *end = data + Step; |     const u64 *end = data + Step; | ||||||
| 	if(samples == 0) samples = max(Step, 1u); |     if(samples == 0) samples = max(Step, 1u); | ||||||
| 	Step = Step / samples; |     Step = Step / samples; | ||||||
| 	if(Step < 1) Step = 1; |     if(Step < 1) Step = 1; | ||||||
| 	while(data < end) |     while(data < end) | ||||||
| 	{ |     { | ||||||
| 		u64 k = data[0]; |         u64 k = data[0]; | ||||||
| 		data+=Step; |         data+=Step; | ||||||
| 		k *= m;  |         k *= m;  | ||||||
| 		k ^= k >> r;  |         k ^= k >> r;  | ||||||
| 		k *= m; |         k *= m; | ||||||
| 		h ^= k; |         h ^= k; | ||||||
| 		h *= m;  |         h *= m;  | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	const u8 * data2 = (const u8*)end; |     const u8 * data2 = (const u8*)end; | ||||||
| 
 | 
 | ||||||
| 	switch(len & 7) |     switch(len & 7) | ||||||
| 	{ |     { | ||||||
| 	case 7: h ^= u64(data2[6]) << 48; |     case 7: h ^= u64(data2[6]) << 48; | ||||||
| 	case 6: h ^= u64(data2[5]) << 40; |     case 6: h ^= u64(data2[5]) << 40; | ||||||
| 	case 5: h ^= u64(data2[4]) << 32; |     case 5: h ^= u64(data2[4]) << 32; | ||||||
| 	case 4: h ^= u64(data2[3]) << 24; |     case 4: h ^= u64(data2[3]) << 24; | ||||||
| 	case 3: h ^= u64(data2[2]) << 16; |     case 3: h ^= u64(data2[2]) << 16; | ||||||
| 	case 2: h ^= u64(data2[1]) << 8; |     case 2: h ^= u64(data2[1]) << 8; | ||||||
| 	case 1: h ^= u64(data2[0]); |     case 1: h ^= u64(data2[0]); | ||||||
| 			h *= m; |             h *= m; | ||||||
| 	}; |     }; | ||||||
|   |   | ||||||
| 	h ^= h >> r; |     h ^= h >> r; | ||||||
| 	h *= m; |     h *= m; | ||||||
| 	h ^= h >> r; |     h ^= h >> r; | ||||||
| 
 | 
 | ||||||
| 	return h; |     return h; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| u64 GetHash64(const u8 *src, int len, u32 samples) | 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
 | // sets the hash function used for the texture cache
 | ||||||
| void SetHash64Function(bool useHiresTextures) | void SetHash64Function(bool useHiresTextures) | ||||||
| { | { | ||||||
| 	if (useHiresTextures) |     if (useHiresTextures) | ||||||
| 	{ |     { | ||||||
| 		ptrHashFunction = &GetHashHiresTexture; |         ptrHashFunction = &GetHashHiresTexture; | ||||||
| 	} |     } | ||||||
| #if _M_SSE >= 0x402 | #if _M_SSE >= 0x402 | ||||||
| 	else if (cpu_info.bSSE4_2 && !useHiresTextures) // sse crc32 version
 |     else if (cpu_info.bSSE4_2 && !useHiresTextures) // sse crc32 version
 | ||||||
| 	{ |     { | ||||||
| 		ptrHashFunction = &GetCRC32; |         ptrHashFunction = &GetCRC32; | ||||||
| 	} |     } | ||||||
| #endif | #endif | ||||||
| 	else |     else | ||||||
| 	{ |     { | ||||||
| 		ptrHashFunction = &GetMurmurHash3; |         ptrHashFunction = &GetMurmurHash3; | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -30,7 +30,7 @@ template <typename K, typename V> | ||||||
| class LinearDiskCacheReader | class LinearDiskCacheReader | ||||||
| { | { | ||||||
| public: | 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.
 | // Dead simple unsorted key-value store with append functionality.
 | ||||||
|  | @ -49,143 +49,143 @@ template <typename K, typename V> | ||||||
| class LinearDiskCache | class LinearDiskCache | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	// return number of read entries
 |     // return number of read entries
 | ||||||
| 	u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader) |     u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader) | ||||||
| 	{ |     { | ||||||
| 		using std::ios_base; |         using std::ios_base; | ||||||
| 
 | 
 | ||||||
| 		// close any currently opened file
 |         // close any currently opened file
 | ||||||
| 		Close(); |         Close(); | ||||||
| 		m_num_entries = 0; |         m_num_entries = 0; | ||||||
| 
 | 
 | ||||||
| 		// try opening for reading/writing
 |         // try opening for reading/writing
 | ||||||
| 		OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary); |         OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary); | ||||||
| 
 | 
 | ||||||
| 		m_file.seekg(0, std::ios::end); |         m_file.seekg(0, std::ios::end); | ||||||
| 		std::fstream::pos_type end_pos = m_file.tellg(); |         std::fstream::pos_type end_pos = m_file.tellg(); | ||||||
| 		m_file.seekg(0, std::ios::beg); |         m_file.seekg(0, std::ios::beg); | ||||||
| 		std::fstream::pos_type start_pos = m_file.tellg(); |         std::fstream::pos_type start_pos = m_file.tellg(); | ||||||
| 		std::streamoff file_size = end_pos - start_pos; |         std::streamoff file_size = end_pos - start_pos; | ||||||
|          |          | ||||||
| 		if (m_file.is_open() && ValidateHeader()) |         if (m_file.is_open() && ValidateHeader()) | ||||||
| 		{ |         { | ||||||
| 			// good header, read some key/value pairs
 |             // good header, read some key/value pairs
 | ||||||
| 			K key; |             K key; | ||||||
| 
 | 
 | ||||||
| 			V *value = NULL; |             V *value = NULL; | ||||||
| 			u32 value_size; |             u32 value_size; | ||||||
| 			u32 entry_number; |             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)) |             while (Read(&value_size)) | ||||||
| 			{ |             { | ||||||
| 				std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size; |                 std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size; | ||||||
| 				if (next_extent > file_size) |                 if (next_extent > file_size) | ||||||
| 					break; |                     break; | ||||||
| 
 | 
 | ||||||
| 				delete[] value; |                 delete[] value; | ||||||
| 				value = new V[value_size]; |                 value = new V[value_size]; | ||||||
| 
 | 
 | ||||||
| 				// read key/value and pass to reader
 |                 // read key/value and pass to reader
 | ||||||
| 				if (Read(&key) && |                 if (Read(&key) && | ||||||
| 					Read(value, value_size) &&  |                     Read(value, value_size) &&  | ||||||
| 					Read(&entry_number) && |                     Read(&entry_number) && | ||||||
| 					entry_number == m_num_entries+1) |                     entry_number == m_num_entries+1) | ||||||
|  				{ |                  { | ||||||
| 					reader.Read(key, value, value_size); |                     reader.Read(key, value, value_size); | ||||||
| 				} |                 } | ||||||
| 				else |                 else | ||||||
| 				{ |                 { | ||||||
| 					break; |                     break; | ||||||
| 				} |                 } | ||||||
| 
 | 
 | ||||||
| 				m_num_entries++; |                 m_num_entries++; | ||||||
| 				last_pos = m_file.tellg(); |                 last_pos = m_file.tellg(); | ||||||
| 			} |             } | ||||||
| 			m_file.seekp(last_pos); |             m_file.seekp(last_pos); | ||||||
| 			m_file.clear(); |             m_file.clear(); | ||||||
| 
 | 
 | ||||||
| 			delete[] value; |             delete[] value; | ||||||
| 			return m_num_entries; |             return m_num_entries; | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		// failed to open file for reading or bad header
 |         // failed to open file for reading or bad header
 | ||||||
| 		// close and recreate file
 |         // close and recreate file
 | ||||||
| 		Close(); |         Close(); | ||||||
| 		m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary); |         m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary); | ||||||
| 		WriteHeader(); |         WriteHeader(); | ||||||
| 		return 0; |         return 0; | ||||||
| 	} |     } | ||||||
|      |      | ||||||
| 	void Sync() |     void Sync() | ||||||
| 	{ |     { | ||||||
| 		m_file.flush(); |         m_file.flush(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void Close() |     void Close() | ||||||
| 	{ |     { | ||||||
| 		if (m_file.is_open()) |         if (m_file.is_open()) | ||||||
| 			m_file.close(); |             m_file.close(); | ||||||
| 		// clear any error flags
 |         // clear any error flags
 | ||||||
| 		m_file.clear(); |         m_file.clear(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// Appends a key-value pair to the store.
 |     // Appends a key-value pair to the store.
 | ||||||
| 	void Append(const K &key, const V *value, u32 value_size) |     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.)
 |         // TODO: Should do a check that we don't already have "key"? (I think each caller does that already.)
 | ||||||
| 		Write(&value_size); |         Write(&value_size); | ||||||
| 		Write(&key); |         Write(&key); | ||||||
| 		Write(value, value_size); |         Write(value, value_size); | ||||||
| 		m_num_entries++; |         m_num_entries++; | ||||||
| 		Write(&m_num_entries); |         Write(&m_num_entries); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	void WriteHeader() |     void WriteHeader() | ||||||
| 	{ |     { | ||||||
| 		Write(&m_header); |         Write(&m_header); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	bool ValidateHeader() |     bool ValidateHeader() | ||||||
| 	{ |     { | ||||||
| 		char file_header[sizeof(Header)]; |         char file_header[sizeof(Header)]; | ||||||
| 
 | 
 | ||||||
| 		return (Read(file_header, sizeof(Header)) |         return (Read(file_header, sizeof(Header)) | ||||||
| 			&& !memcmp((const char*)&m_header, file_header, sizeof(Header))); |             && !memcmp((const char*)&m_header, file_header, sizeof(Header))); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	template <typename D> |     template <typename D> | ||||||
| 	bool Write(const D *data, u32 count = 1) |     bool Write(const D *data, u32 count = 1) | ||||||
| 	{ |     { | ||||||
| 		return m_file.write((const char*)data, count * sizeof(D)).good(); |         return m_file.write((const char*)data, count * sizeof(D)).good(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	template <typename D> |     template <typename D> | ||||||
| 	bool Read(const D *data, u32 count = 1) |     bool Read(const D *data, u32 count = 1) | ||||||
| 	{ |     { | ||||||
| 		return m_file.read((char*)data, count * sizeof(D)).good(); |         return m_file.read((char*)data, count * sizeof(D)).good(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	struct Header |     struct Header | ||||||
| 	{ |     { | ||||||
| 		Header() |         Header() | ||||||
| 			: id(*(u32*)"DCAC") |             : id(*(u32*)"DCAC") | ||||||
| 			, key_t_size(sizeof(K)) |             , key_t_size(sizeof(K)) | ||||||
| 			, value_t_size(sizeof(V)) |             , value_t_size(sizeof(V)) | ||||||
| 		{ |         { | ||||||
| 			memcpy(ver, scm_rev_git_str, 40); |             memcpy(ver, scm_rev_git_str, 40); | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		const u32 id; |         const u32 id; | ||||||
| 		const u16 key_t_size, value_t_size; |         const u16 key_t_size, value_t_size; | ||||||
| 		char ver[40]; |         char ver[40]; | ||||||
| 
 | 
 | ||||||
| 	} m_header; |     } m_header; | ||||||
| 
 | 
 | ||||||
| 	std::fstream m_file; |     std::fstream m_file; | ||||||
| 	u32 m_num_entries; |     u32 m_num_entries; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif  // _LINEAR_DISKCACHE
 | #endif  // _LINEAR_DISKCACHE
 | ||||||
|  |  | ||||||
|  | @ -5,74 +5,74 @@ | ||||||
| #ifndef _LOG_H_ | #ifndef _LOG_H_ | ||||||
| #define _LOG_H_ | #define _LOG_H_ | ||||||
| 
 | 
 | ||||||
| #define	NOTICE_LEVEL  1  // VERY important information that is NOT errors. Like startup and OSReports.
 | #define    NOTICE_LEVEL  1  // VERY important information that is NOT errors. Like startup and OSReports.
 | ||||||
| #define	ERROR_LEVEL   2  // Critical errors 
 | #define    ERROR_LEVEL   2  // Critical errors 
 | ||||||
| #define	WARNING_LEVEL 3  // Something is suspicious.
 | #define    WARNING_LEVEL 3  // Something is suspicious.
 | ||||||
| #define	INFO_LEVEL    4  // General information.
 | #define    INFO_LEVEL    4  // General information.
 | ||||||
| #define	DEBUG_LEVEL   5  // Detailed debugging - might make things slow.
 | #define    DEBUG_LEVEL   5  // Detailed debugging - might make things slow.
 | ||||||
| 
 | 
 | ||||||
| namespace LogTypes | namespace LogTypes | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| enum LOG_TYPE { | enum LOG_TYPE { | ||||||
| 	ACTIONREPLAY, |     ACTIONREPLAY, | ||||||
| 	AUDIO, |     AUDIO, | ||||||
| 	AUDIO_INTERFACE, |     AUDIO_INTERFACE, | ||||||
| 	BOOT, |     BOOT, | ||||||
| 	COMMANDPROCESSOR, |     COMMANDPROCESSOR, | ||||||
| 	COMMON, |     COMMON, | ||||||
| 	CONSOLE, |     CONSOLE, | ||||||
| 	DISCIO, |     DISCIO, | ||||||
| 	FILEMON, |     FILEMON, | ||||||
| 	DSPHLE, |     DSPHLE, | ||||||
| 	DSPLLE, |     DSPLLE, | ||||||
| 	DSP_MAIL, |     DSP_MAIL, | ||||||
| 	DSPINTERFACE, |     DSPINTERFACE, | ||||||
| 	DVDINTERFACE, |     DVDINTERFACE, | ||||||
| 	DYNA_REC, |     DYNA_REC, | ||||||
| 	EXPANSIONINTERFACE, |     EXPANSIONINTERFACE, | ||||||
| 	GDB_STUB, |     GDB_STUB, | ||||||
| 	ARM11, |     ARM11, | ||||||
| 	GPFIFO, |     GPFIFO, | ||||||
| 	OSHLE, |     OSHLE, | ||||||
| 	MASTER_LOG, |     MASTER_LOG, | ||||||
| 	MEMMAP, |     MEMMAP, | ||||||
| 	MEMCARD_MANAGER, |     MEMCARD_MANAGER, | ||||||
| 	OSREPORT, |     OSREPORT, | ||||||
| 	PAD,  |     PAD,  | ||||||
| 	PROCESSORINTERFACE, |     PROCESSORINTERFACE, | ||||||
| 	PIXELENGINE, |     PIXELENGINE, | ||||||
| 	SERIALINTERFACE, |     SERIALINTERFACE, | ||||||
| 	SP1, |     SP1, | ||||||
| 	STREAMINGINTERFACE, |     STREAMINGINTERFACE, | ||||||
| 	VIDEO, |     VIDEO, | ||||||
| 	VIDEOINTERFACE, |     VIDEOINTERFACE, | ||||||
| 	LOADER, |     LOADER, | ||||||
| 	FILESYS, |     FILESYS, | ||||||
| 	WII_IPC_DVD, |     WII_IPC_DVD, | ||||||
| 	WII_IPC_ES, |     WII_IPC_ES, | ||||||
| 	WII_IPC_FILEIO, |     WII_IPC_FILEIO, | ||||||
| 	WII_IPC_HID, |     WII_IPC_HID, | ||||||
| 	WII_IPC_HLE, |     WII_IPC_HLE, | ||||||
| 	WII_IPC_NET, |     WII_IPC_NET, | ||||||
| 	WII_IPC_WC24, |     WII_IPC_WC24, | ||||||
| 	WII_IPC_SSL, |     WII_IPC_SSL, | ||||||
| 	WII_IPC_SD, |     WII_IPC_SD, | ||||||
| 	WII_IPC_STM, |     WII_IPC_STM, | ||||||
| 	WII_IPC_WIIMOTE, |     WII_IPC_WIIMOTE, | ||||||
| 	TIME, |     TIME, | ||||||
| 	NETPLAY, |     NETPLAY, | ||||||
| 
 | 
 | ||||||
| 	NUMBER_OF_LOGS // Must be last
 |     NUMBER_OF_LOGS // Must be last
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // FIXME: should this be removed?
 | // FIXME: should this be removed?
 | ||||||
| enum LOG_LEVELS { | enum LOG_LEVELS { | ||||||
| 	LNOTICE = NOTICE_LEVEL, |     LNOTICE = NOTICE_LEVEL, | ||||||
| 	LERROR = ERROR_LEVEL, |     LERROR = ERROR_LEVEL, | ||||||
| 	LWARNING = WARNING_LEVEL, |     LWARNING = WARNING_LEVEL, | ||||||
| 	LINFO = INFO_LEVEL, |     LINFO = INFO_LEVEL, | ||||||
| 	LDEBUG = DEBUG_LEVEL, |     LDEBUG = DEBUG_LEVEL, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #define LOGTYPES_LEVELS LogTypes::LOG_LEVELS | #define LOGTYPES_LEVELS LogTypes::LOG_LEVELS | ||||||
|  | @ -81,11 +81,11 @@ enum LOG_LEVELS { | ||||||
| }  // namespace
 | }  // namespace
 | ||||||
| 
 | 
 | ||||||
| void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, | 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__ | #ifdef __GNUC__ | ||||||
| 		__attribute__((format(printf, 5, 6))) |         __attribute__((format(printf, 5, 6))) | ||||||
| #endif | #endif | ||||||
| 		; |         ; | ||||||
| 
 | 
 | ||||||
| #if defined LOGGING || defined _DEBUG || defined DEBUGFAST | #if defined LOGGING || defined _DEBUG || defined DEBUGFAST | ||||||
| #define MAX_LOGLEVEL DEBUG_LEVEL | #define MAX_LOGLEVEL DEBUG_LEVEL | ||||||
|  | @ -100,9 +100,9 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, | ||||||
| #else | #else | ||||||
| // Let the compiler optimize this out
 | // Let the compiler optimize this out
 | ||||||
| #define GENERIC_LOG(t, v, ...) { \ | #define GENERIC_LOG(t, v, ...) { \ | ||||||
| 	if (v <= MAX_LOGLEVEL) \ |     if (v <= MAX_LOGLEVEL) \ | ||||||
| 		GenericLog(v, t, __FILE__, __LINE__, __VA_ARGS__); \ |         GenericLog(v, t, __FILE__, __LINE__, __VA_ARGS__); \ | ||||||
| 	} |     } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #define ERROR_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LERROR, __VA_ARGS__) } while (0) | #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 | #if MAX_LOGLEVEL >= DEBUG_LEVEL | ||||||
| #define _dbg_assert_(_t_, _a_) \ | #define _dbg_assert_(_t_, _a_) \ | ||||||
| 	if (!(_a_)) {\ |     if (!(_a_)) {\ | ||||||
| 		ERROR_LOG(_t_, "Error...\n\n  Line: %d\n  File: %s\n  Time: %s\n\nIgnore and continue?", \ |         ERROR_LOG(_t_, "Error...\n\n  Line: %d\n  File: %s\n  Time: %s\n\nIgnore and continue?", \ | ||||||
| 					   __LINE__, __FILE__, __TIME__); \ |                        __LINE__, __FILE__, __TIME__); \ | ||||||
| 		if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \ |         if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \ | ||||||
| 	} |     } | ||||||
| #define _dbg_assert_msg_(_t_, _a_, ...)\ | #define _dbg_assert_msg_(_t_, _a_, ...)\ | ||||||
| 	if (!(_a_)) {\ |     if (!(_a_)) {\ | ||||||
| 		ERROR_LOG(_t_, __VA_ARGS__); \ |         ERROR_LOG(_t_, __VA_ARGS__); \ | ||||||
| 		if (!PanicYesNo(__VA_ARGS__)) {Crash();} \ |         if (!PanicYesNo(__VA_ARGS__)) {Crash();} \ | ||||||
| 	} |     } | ||||||
| #define _dbg_update_() Host_UpdateLogDisplay(); | #define _dbg_update_() Host_UpdateLogDisplay(); | ||||||
| 
 | 
 | ||||||
| #else // not debug
 | #else // not debug
 | ||||||
|  | @ -138,15 +138,15 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, | ||||||
| 
 | 
 | ||||||
| #ifndef GEKKO | #ifndef GEKKO | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| #define _assert_msg_(_t_, _a_, _fmt_, ...)		\ | #define _assert_msg_(_t_, _a_, _fmt_, ...)        \ | ||||||
| 	if (!(_a_)) {\ |     if (!(_a_)) {\ | ||||||
| 		if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \ |         if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \ | ||||||
| 	} |     } | ||||||
| #else // not win32
 | #else // not win32
 | ||||||
| #define _assert_msg_(_t_, _a_, _fmt_, ...)		\ | #define _assert_msg_(_t_, _a_, _fmt_, ...)        \ | ||||||
| 	if (!(_a_)) {\ |     if (!(_a_)) {\ | ||||||
| 		if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \ |         if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \ | ||||||
| 	} |     } | ||||||
| #endif // WIN32
 | #endif // WIN32
 | ||||||
| #else // GEKKO
 | #else // GEKKO
 | ||||||
| #define _assert_msg_(_t_, _a_, _fmt_, ...) | #define _assert_msg_(_t_, _a_, _fmt_, ...) | ||||||
|  |  | ||||||
|  | @ -14,187 +14,187 @@ | ||||||
| #include "file_util.h" | #include "file_util.h" | ||||||
| 
 | 
 | ||||||
| void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,  | 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_list args; | ||||||
| 	va_start(args, fmt); |     va_start(args, fmt); | ||||||
| 	if (LogManager::GetInstance()) |     if (LogManager::GetInstance()) | ||||||
| 		LogManager::GetInstance()->Log(level, type, |         LogManager::GetInstance()->Log(level, type, | ||||||
| 			file, line, fmt, args); |             file, line, fmt, args); | ||||||
| 	va_end(args); |     va_end(args); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| LogManager *LogManager::m_logManager = NULL; | LogManager *LogManager::m_logManager = NULL; | ||||||
| 
 | 
 | ||||||
| LogManager::LogManager() | LogManager::LogManager() | ||||||
| { | { | ||||||
| 	// create log files
 |     // create log files
 | ||||||
| 	m_Log[LogTypes::MASTER_LOG]			= new LogContainer("*",				"Master Log"); |     m_Log[LogTypes::MASTER_LOG]            = new LogContainer("*",                "Master Log"); | ||||||
| 	m_Log[LogTypes::BOOT]				= new LogContainer("BOOT",			"Boot"); |     m_Log[LogTypes::BOOT]                = new LogContainer("BOOT",            "Boot"); | ||||||
| 	m_Log[LogTypes::COMMON]				= new LogContainer("COMMON",		"Common"); |     m_Log[LogTypes::COMMON]                = new LogContainer("COMMON",        "Common"); | ||||||
| 	m_Log[LogTypes::DISCIO]				= new LogContainer("DIO",			"Disc IO"); |     m_Log[LogTypes::DISCIO]                = new LogContainer("DIO",            "Disc IO"); | ||||||
| 	m_Log[LogTypes::FILEMON]			= new LogContainer("FileMon",		"File Monitor"); |     m_Log[LogTypes::FILEMON]            = new LogContainer("FileMon",        "File Monitor"); | ||||||
| 	m_Log[LogTypes::PAD]				= new LogContainer("PAD",			"Pad"); |     m_Log[LogTypes::PAD]                = new LogContainer("PAD",            "Pad"); | ||||||
| 	m_Log[LogTypes::PIXELENGINE]		= new LogContainer("PE",			"PixelEngine"); |     m_Log[LogTypes::PIXELENGINE]        = new LogContainer("PE",            "PixelEngine"); | ||||||
| 	m_Log[LogTypes::COMMANDPROCESSOR]	= new LogContainer("CP",			"CommandProc"); |     m_Log[LogTypes::COMMANDPROCESSOR]    = new LogContainer("CP",            "CommandProc"); | ||||||
| 	m_Log[LogTypes::VIDEOINTERFACE]		= new LogContainer("VI",			"VideoInt"); |     m_Log[LogTypes::VIDEOINTERFACE]        = new LogContainer("VI",            "VideoInt"); | ||||||
| 	m_Log[LogTypes::SERIALINTERFACE]	= new LogContainer("SI",			"SerialInt"); |     m_Log[LogTypes::SERIALINTERFACE]    = new LogContainer("SI",            "SerialInt"); | ||||||
| 	m_Log[LogTypes::PROCESSORINTERFACE]	= new LogContainer("PI",			"ProcessorInt"); |     m_Log[LogTypes::PROCESSORINTERFACE]    = new LogContainer("PI",            "ProcessorInt"); | ||||||
| 	m_Log[LogTypes::MEMMAP]				= new LogContainer("MI",			"MI & memmap"); |     m_Log[LogTypes::MEMMAP]                = new LogContainer("MI",            "MI & memmap"); | ||||||
| 	m_Log[LogTypes::SP1]				= new LogContainer("SP1",			"Serial Port 1"); |     m_Log[LogTypes::SP1]                = new LogContainer("SP1",            "Serial Port 1"); | ||||||
| 	m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream",		"StreamingInt"); |     m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream",        "StreamingInt"); | ||||||
| 	m_Log[LogTypes::DSPINTERFACE]		= new LogContainer("DSP",			"DSPInterface"); |     m_Log[LogTypes::DSPINTERFACE]        = new LogContainer("DSP",            "DSPInterface"); | ||||||
| 	m_Log[LogTypes::DVDINTERFACE]		= new LogContainer("DVD",			"DVDInterface"); |     m_Log[LogTypes::DVDINTERFACE]        = new LogContainer("DVD",            "DVDInterface"); | ||||||
| 	m_Log[LogTypes::GPFIFO]				= new LogContainer("GP",			"GPFifo"); |     m_Log[LogTypes::GPFIFO]                = new LogContainer("GP",            "GPFifo"); | ||||||
| 	m_Log[LogTypes::EXPANSIONINTERFACE]	= new LogContainer("EXI",			"ExpansionInt"); |     m_Log[LogTypes::EXPANSIONINTERFACE]    = new LogContainer("EXI",            "ExpansionInt"); | ||||||
| 	m_Log[LogTypes::GDB_STUB]			= new LogContainer("GDB_STUB",		"GDB Stub"); |     m_Log[LogTypes::GDB_STUB]            = new LogContainer("GDB_STUB",        "GDB Stub"); | ||||||
| 	m_Log[LogTypes::AUDIO_INTERFACE]	= new LogContainer("AI",			"AudioInt"); |     m_Log[LogTypes::AUDIO_INTERFACE]    = new LogContainer("AI",            "AudioInt"); | ||||||
| 	m_Log[LogTypes::ARM11]				= new LogContainer("ARM11",			"ARM11"); |     m_Log[LogTypes::ARM11]                = new LogContainer("ARM11",            "ARM11"); | ||||||
| 	m_Log[LogTypes::OSHLE]				= new LogContainer("HLE",			"HLE"); |     m_Log[LogTypes::OSHLE]                = new LogContainer("HLE",            "HLE"); | ||||||
| 	m_Log[LogTypes::DSPHLE]				= new LogContainer("DSPHLE",		"DSP HLE"); |     m_Log[LogTypes::DSPHLE]                = new LogContainer("DSPHLE",        "DSP HLE"); | ||||||
| 	m_Log[LogTypes::DSPLLE]				= new LogContainer("DSPLLE",		"DSP LLE"); |     m_Log[LogTypes::DSPLLE]                = new LogContainer("DSPLLE",        "DSP LLE"); | ||||||
| 	m_Log[LogTypes::DSP_MAIL]			= new LogContainer("DSPMails",		"DSP Mails"); |     m_Log[LogTypes::DSP_MAIL]            = new LogContainer("DSPMails",        "DSP Mails"); | ||||||
| 	m_Log[LogTypes::VIDEO]				= new LogContainer("Video",			"Video Backend"); |     m_Log[LogTypes::VIDEO]                = new LogContainer("Video",            "Video Backend"); | ||||||
| 	m_Log[LogTypes::AUDIO]				= new LogContainer("Audio",			"Audio Emulator"); |     m_Log[LogTypes::AUDIO]                = new LogContainer("Audio",            "Audio Emulator"); | ||||||
| 	m_Log[LogTypes::DYNA_REC]			= new LogContainer("JIT",			"Dynamic Recompiler"); |     m_Log[LogTypes::DYNA_REC]            = new LogContainer("JIT",            "Dynamic Recompiler"); | ||||||
| 	m_Log[LogTypes::CONSOLE]			= new LogContainer("CONSOLE",		"Dolphin Console"); |     m_Log[LogTypes::CONSOLE]            = new LogContainer("CONSOLE",        "Dolphin Console"); | ||||||
| 	m_Log[LogTypes::OSREPORT]			= new LogContainer("OSREPORT",		"OSReport"); |     m_Log[LogTypes::OSREPORT]            = new LogContainer("OSREPORT",        "OSReport"); | ||||||
| 	m_Log[LogTypes::TIME]				= new LogContainer("Time",			"Core Timing"); |     m_Log[LogTypes::TIME]                = new LogContainer("Time",            "Core Timing"); | ||||||
| 	m_Log[LogTypes::LOADER]				= new LogContainer("Loader",		"Loader"); |     m_Log[LogTypes::LOADER]                = new LogContainer("Loader",        "Loader"); | ||||||
| 	m_Log[LogTypes::FILESYS]			= new LogContainer("FileSys",		"File System"); |     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_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_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_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_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_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_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_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_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_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_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::WII_IPC_WIIMOTE]    = new LogContainer("WII_IPC_WIIMOTE","WII IPC WIIMOTE"); | ||||||
| 	m_Log[LogTypes::ACTIONREPLAY]		= new LogContainer("ActionReplay",	"ActionReplay"); |     m_Log[LogTypes::ACTIONREPLAY]        = new LogContainer("ActionReplay",    "ActionReplay"); | ||||||
| 	m_Log[LogTypes::MEMCARD_MANAGER]	= new LogContainer("MemCard Manager", "MemCard Manager"); |     m_Log[LogTypes::MEMCARD_MANAGER]    = new LogContainer("MemCard Manager", "MemCard Manager"); | ||||||
| 	m_Log[LogTypes::NETPLAY]			= new LogContainer("NETPLAY",		"Netplay"); |     m_Log[LogTypes::NETPLAY]            = new LogContainer("NETPLAY",        "Netplay"); | ||||||
| 
 | 
 | ||||||
| 	m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str()); |     m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str()); | ||||||
| 	m_consoleLog = new ConsoleListener(); |     m_consoleLog = new ConsoleListener(); | ||||||
| 	m_debuggerLog = new DebuggerLogListener(); |     m_debuggerLog = new DebuggerLogListener(); | ||||||
| 
 | 
 | ||||||
| 	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) |     for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | ||||||
| 	{ |     { | ||||||
| 		m_Log[i]->SetEnable(true); |         m_Log[i]->SetEnable(true); | ||||||
| 		m_Log[i]->AddListener(m_fileLog); |         m_Log[i]->AddListener(m_fileLog); | ||||||
| 		m_Log[i]->AddListener(m_consoleLog); |         m_Log[i]->AddListener(m_consoleLog); | ||||||
| #ifdef _MSC_VER | #ifdef _MSC_VER | ||||||
| 		if (IsDebuggerPresent()) |         if (IsDebuggerPresent()) | ||||||
| 			m_Log[i]->AddListener(m_debuggerLog); |             m_Log[i]->AddListener(m_debuggerLog); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| LogManager::~LogManager() | LogManager::~LogManager() | ||||||
| { | { | ||||||
| 	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) |     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_fileLog); | ||||||
| 		m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog); |         m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog); | ||||||
| 		m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_debuggerLog); |         m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_debuggerLog); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) |     for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | ||||||
| 		delete m_Log[i]; |         delete m_Log[i]; | ||||||
| 
 | 
 | ||||||
| 	delete m_fileLog; |     delete m_fileLog; | ||||||
| 	delete m_consoleLog; |     delete m_consoleLog; | ||||||
| 	delete m_debuggerLog; |     delete m_debuggerLog; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,  | 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 temp[MAX_MSGLEN]; | ||||||
| 	char msg[MAX_MSGLEN * 2]; |     char msg[MAX_MSGLEN * 2]; | ||||||
| 	LogContainer *log = m_Log[type]; |     LogContainer *log = m_Log[type]; | ||||||
| 
 | 
 | ||||||
| 	if (!log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners()) |     if (!log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners()) | ||||||
| 		return; |         return; | ||||||
| 
 | 
 | ||||||
| 	CharArrayFromFormatV(temp, MAX_MSGLEN, format, args); |     CharArrayFromFormatV(temp, MAX_MSGLEN, format, args); | ||||||
| 
 | 
 | ||||||
| 	static const char level_to_char[7] = "-NEWID"; |     static const char level_to_char[7] = "-NEWID"; | ||||||
| 	sprintf(msg, "%s %s:%u %c[%s]: %s\n", |     sprintf(msg, "%s %s:%u %c[%s]: %s\n", | ||||||
| 		Common::Timer::GetTimeFormatted().c_str(), |         Common::Timer::GetTimeFormatted().c_str(), | ||||||
| 		file, line, level_to_char[(int)level], |         file, line, level_to_char[(int)level], | ||||||
| 		log->GetShortName(), temp); |         log->GetShortName(), temp); | ||||||
| #ifdef ANDROID | #ifdef ANDROID | ||||||
| 	Host_SysMessage(msg);	 |     Host_SysMessage(msg);     | ||||||
| #endif | #endif | ||||||
| 	printf(msg); // TODO(ShizZy): RemoveMe when I no longer need this
 |     printf(msg); // TODO(ShizZy): RemoveMe when I no longer need this
 | ||||||
| 	log->Trigger(level, msg); |     log->Trigger(level, msg); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LogManager::Init() | void LogManager::Init() | ||||||
| { | { | ||||||
| 	m_logManager = new LogManager(); |     m_logManager = new LogManager(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LogManager::Shutdown() | void LogManager::Shutdown() | ||||||
| { | { | ||||||
| 	delete m_logManager; |     delete m_logManager; | ||||||
| 	m_logManager = NULL; |     m_logManager = NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| LogContainer::LogContainer(const char* shortName, const char* fullName, bool enable) | LogContainer::LogContainer(const char* shortName, const char* fullName, bool enable) | ||||||
| 	: m_enable(enable) |     : m_enable(enable) | ||||||
| { | { | ||||||
| 	strncpy(m_fullName, fullName, 128); |     strncpy(m_fullName, fullName, 128); | ||||||
| 	strncpy(m_shortName, shortName, 32); |     strncpy(m_shortName, shortName, 32); | ||||||
| 	m_level = LogTypes::LWARNING; |     m_level = LogTypes::LWARNING; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // LogContainer
 | // LogContainer
 | ||||||
| void LogContainer::AddListener(LogListener *listener) | void LogContainer::AddListener(LogListener *listener) | ||||||
| { | { | ||||||
| 	std::lock_guard<std::mutex> lk(m_listeners_lock); |     std::lock_guard<std::mutex> lk(m_listeners_lock); | ||||||
| 	m_listeners.insert(listener); |     m_listeners.insert(listener); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LogContainer::RemoveListener(LogListener *listener) | void LogContainer::RemoveListener(LogListener *listener) | ||||||
| { | { | ||||||
| 	std::lock_guard<std::mutex> lk(m_listeners_lock); |     std::lock_guard<std::mutex> lk(m_listeners_lock); | ||||||
| 	m_listeners.erase(listener); |     m_listeners.erase(listener); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LogContainer::Trigger(LogTypes::LOG_LEVELS level, const char *msg) | 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; |     std::set<LogListener*>::const_iterator i; | ||||||
| 	for (i = m_listeners.begin(); i != m_listeners.end(); ++i) |     for (i = m_listeners.begin(); i != m_listeners.end(); ++i) | ||||||
| 	{ |     { | ||||||
| 		(*i)->Log(level, msg); |         (*i)->Log(level, msg); | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FileLogListener::FileLogListener(const char *filename) | FileLogListener::FileLogListener(const char *filename) | ||||||
| { | { | ||||||
| 	OpenFStream(m_logfile, filename, std::ios::app); |     OpenFStream(m_logfile, filename, std::ios::app); | ||||||
| 	SetEnable(true); |     SetEnable(true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) | void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) | ||||||
| { | { | ||||||
| 	if (!IsEnabled() || !IsValid()) |     if (!IsEnabled() || !IsValid()) | ||||||
| 		return; |         return; | ||||||
| 
 | 
 | ||||||
| 	std::lock_guard<std::mutex> lk(m_log_lock); |     std::lock_guard<std::mutex> lk(m_log_lock); | ||||||
| 	m_logfile << msg << std::flush; |     m_logfile << msg << std::flush; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void DebuggerLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) | void DebuggerLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) | ||||||
| { | { | ||||||
| #if _MSC_VER | #if _MSC_VER | ||||||
| 	::OutputDebugStringA(msg); |     ::OutputDebugStringA(msg); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -21,65 +21,65 @@ | ||||||
| class LogListener | class LogListener | ||||||
| { | { | ||||||
| public: | 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 | class FileLogListener : public LogListener | ||||||
| { | { | ||||||
| public: | 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 IsValid() { return !m_logfile.fail(); } | ||||||
| 	bool IsEnabled() const { return m_enable; } |     bool IsEnabled() const { return m_enable; } | ||||||
| 	void SetEnable(bool enable) { m_enable = enable; } |     void SetEnable(bool enable) { m_enable = enable; } | ||||||
| 
 | 
 | ||||||
| 	const char* GetName() const { return "file"; } |     const char* GetName() const { return "file"; } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	std::mutex m_log_lock; |     std::mutex m_log_lock; | ||||||
| 	std::ofstream m_logfile; |     std::ofstream m_logfile; | ||||||
| 	bool m_enable; |     bool m_enable; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class DebuggerLogListener : public LogListener | class DebuggerLogListener : public LogListener | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	void Log(LogTypes::LOG_LEVELS, const char *msg); |     void Log(LogTypes::LOG_LEVELS, const char *msg); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class LogContainer | class LogContainer | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	LogContainer(const char* shortName, const char* fullName, bool enable = false); |     LogContainer(const char* shortName, const char* fullName, bool enable = false); | ||||||
|      |      | ||||||
| 	const char* GetShortName() const { return m_shortName; } |     const char* GetShortName() const { return m_shortName; } | ||||||
| 	const char* GetFullName() const { return m_fullName; } |     const char* GetFullName() const { return m_fullName; } | ||||||
| 
 | 
 | ||||||
| 	void AddListener(LogListener* listener); |     void AddListener(LogListener* listener); | ||||||
| 	void RemoveListener(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; } |     bool IsEnabled() const { return m_enable; } | ||||||
| 	void SetEnable(bool enable) { m_enable = 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: | private: | ||||||
| 	char m_fullName[128]; |     char m_fullName[128]; | ||||||
| 	char m_shortName[32]; |     char m_shortName[32]; | ||||||
| 	bool m_enable; |     bool m_enable; | ||||||
| 	LogTypes::LOG_LEVELS m_level; |     LogTypes::LOG_LEVELS m_level; | ||||||
| 	std::mutex m_listeners_lock; |     std::mutex m_listeners_lock; | ||||||
| 	std::set<LogListener*> m_listeners; |     std::set<LogListener*> m_listeners; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class ConsoleListener; | class ConsoleListener; | ||||||
|  | @ -87,83 +87,83 @@ class ConsoleListener; | ||||||
| class LogManager : NonCopyable | class LogManager : NonCopyable | ||||||
| { | { | ||||||
| private: | private: | ||||||
| 	LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS]; |     LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS]; | ||||||
| 	FileLogListener *m_fileLog; |     FileLogListener *m_fileLog; | ||||||
| 	ConsoleListener *m_consoleLog; |     ConsoleListener *m_consoleLog; | ||||||
| 	DebuggerLogListener *m_debuggerLog; |     DebuggerLogListener *m_debuggerLog; | ||||||
| 	static LogManager *m_logManager;  // Singleton. Ugh.
 |     static LogManager *m_logManager;  // Singleton. Ugh.
 | ||||||
| 
 | 
 | ||||||
| 	LogManager(); |     LogManager(); | ||||||
| 	~LogManager(); |     ~LogManager(); | ||||||
| public: | public: | ||||||
| 
 | 
 | ||||||
| 	static u32 GetMaxLevel() { return MAX_LOGLEVEL;	} |     static u32 GetMaxLevel() { return MAX_LOGLEVEL;    } | ||||||
| 
 | 
 | ||||||
| 	void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,  |     void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,  | ||||||
| 			 const char *file, int line, const char *fmt, va_list args); |              const char *file, int line, const char *fmt, va_list args); | ||||||
| 
 | 
 | ||||||
| 	void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level) |     void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level) | ||||||
| 	{ |     { | ||||||
| 		m_Log[type]->SetLevel(level); |         m_Log[type]->SetLevel(level); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void SetEnable(LogTypes::LOG_TYPE type, bool enable) |     void SetEnable(LogTypes::LOG_TYPE type, bool enable) | ||||||
| 	{ |     { | ||||||
| 		m_Log[type]->SetEnable(enable); |         m_Log[type]->SetEnable(enable); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	bool IsEnabled(LogTypes::LOG_TYPE type) const |     bool IsEnabled(LogTypes::LOG_TYPE type) const | ||||||
| 	{ |     { | ||||||
| 		return m_Log[type]->IsEnabled(); |         return m_Log[type]->IsEnabled(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	const char* GetShortName(LogTypes::LOG_TYPE type) const |     const char* GetShortName(LogTypes::LOG_TYPE type) const | ||||||
| 	{ |     { | ||||||
| 		return m_Log[type]->GetShortName(); |         return m_Log[type]->GetShortName(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	const char* GetFullName(LogTypes::LOG_TYPE type) const |     const char* GetFullName(LogTypes::LOG_TYPE type) const | ||||||
| 	{ |     { | ||||||
| 		return m_Log[type]->GetFullName(); |         return m_Log[type]->GetFullName(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void AddListener(LogTypes::LOG_TYPE type, LogListener *listener) |     void AddListener(LogTypes::LOG_TYPE type, LogListener *listener) | ||||||
| 	{ |     { | ||||||
| 		m_Log[type]->AddListener(listener); |         m_Log[type]->AddListener(listener); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener) |     void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener) | ||||||
| 	{ |     { | ||||||
| 		m_Log[type]->RemoveListener(listener); |         m_Log[type]->RemoveListener(listener); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	FileLogListener *GetFileListener() const |     FileLogListener *GetFileListener() const | ||||||
| 	{ |     { | ||||||
| 		return m_fileLog; |         return m_fileLog; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	ConsoleListener *GetConsoleListener() const |     ConsoleListener *GetConsoleListener() const | ||||||
| 	{ |     { | ||||||
| 		return m_consoleLog; |         return m_consoleLog; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	DebuggerLogListener *GetDebuggerListener() const |     DebuggerLogListener *GetDebuggerListener() const | ||||||
| 	{ |     { | ||||||
| 		return m_debuggerLog; |         return m_debuggerLog; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	static LogManager* GetInstance() |     static LogManager* GetInstance() | ||||||
| 	{ |     { | ||||||
| 		return m_logManager; |         return m_logManager; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	static void SetInstance(LogManager *logManager) |     static void SetInstance(LogManager *logManager) | ||||||
| 	{ |     { | ||||||
| 		m_logManager = logManager; |         m_logManager = logManager; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	static void Init(); |     static void Init(); | ||||||
| 	static void Shutdown(); |     static void Shutdown(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // _LOGMANAGER_H_
 | #endif // _LOGMANAGER_H_
 | ||||||
|  |  | ||||||
|  | @ -14,82 +14,82 @@ namespace MathUtil | ||||||
| 
 | 
 | ||||||
| u32 ClassifyDouble(double dvalue) | u32 ClassifyDouble(double dvalue) | ||||||
| { | { | ||||||
| 	// TODO: Optimize the below to be as fast as possible.
 |     // TODO: Optimize the below to be as fast as possible.
 | ||||||
| 	IntDouble value; |     IntDouble value; | ||||||
| 	value.d = dvalue; |     value.d = dvalue; | ||||||
| 	u64 sign = value.i & DOUBLE_SIGN; |     u64 sign = value.i & DOUBLE_SIGN; | ||||||
| 	u64 exp  = value.i & DOUBLE_EXP; |     u64 exp  = value.i & DOUBLE_EXP; | ||||||
| 	if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP)  |     if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP)  | ||||||
| 	{ |     { | ||||||
| 		// Nice normalized number.
 |         // Nice normalized number.
 | ||||||
| 		return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; |         return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; | ||||||
| 	} |     } | ||||||
| 	else |     else | ||||||
| 	{ |     { | ||||||
| 		u64 mantissa = value.i & DOUBLE_FRAC; |         u64 mantissa = value.i & DOUBLE_FRAC; | ||||||
| 		if (mantissa) |         if (mantissa) | ||||||
| 		{ |         { | ||||||
| 			if (exp) |             if (exp) | ||||||
| 			{ |             { | ||||||
| 				return PPC_FPCLASS_QNAN; |                 return PPC_FPCLASS_QNAN; | ||||||
| 			} |             } | ||||||
| 			else |             else | ||||||
| 			{ |             { | ||||||
| 				// Denormalized number.
 |                 // Denormalized number.
 | ||||||
| 				return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; |                 return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; | ||||||
| 			} |             } | ||||||
| 		} |         } | ||||||
| 		else if (exp) |         else if (exp) | ||||||
| 		{ |         { | ||||||
| 			//Infinite
 |             //Infinite
 | ||||||
| 			return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; |             return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; | ||||||
| 		} |         } | ||||||
| 		else |         else | ||||||
| 		{ |         { | ||||||
| 			//Zero
 |             //Zero
 | ||||||
| 			return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; |             return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u32 ClassifyFloat(float fvalue) | u32 ClassifyFloat(float fvalue) | ||||||
| { | { | ||||||
| 	// TODO: Optimize the below to be as fast as possible.
 |     // TODO: Optimize the below to be as fast as possible.
 | ||||||
| 	IntFloat value; |     IntFloat value; | ||||||
| 	value.f = fvalue; |     value.f = fvalue; | ||||||
| 	u32 sign = value.i & FLOAT_SIGN; |     u32 sign = value.i & FLOAT_SIGN; | ||||||
| 	u32 exp  = value.i & FLOAT_EXP; |     u32 exp  = value.i & FLOAT_EXP; | ||||||
| 	if (exp > FLOAT_ZERO && exp < FLOAT_EXP)  |     if (exp > FLOAT_ZERO && exp < FLOAT_EXP)  | ||||||
| 	{ |     { | ||||||
| 		// Nice normalized number.
 |         // Nice normalized number.
 | ||||||
| 		return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; |         return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; | ||||||
| 	} |     } | ||||||
| 	else |     else | ||||||
| 	{ |     { | ||||||
| 		u32 mantissa = value.i & FLOAT_FRAC; |         u32 mantissa = value.i & FLOAT_FRAC; | ||||||
| 		if (mantissa) |         if (mantissa) | ||||||
| 		{ |         { | ||||||
| 			if (exp) |             if (exp) | ||||||
| 			{ |             { | ||||||
| 				return PPC_FPCLASS_QNAN; // Quiet NAN
 |                 return PPC_FPCLASS_QNAN; // Quiet NAN
 | ||||||
| 			} |             } | ||||||
| 			else |             else | ||||||
| 			{ |             { | ||||||
| 				// Denormalized number.
 |                 // Denormalized number.
 | ||||||
| 				return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; |                 return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; | ||||||
| 			} |             } | ||||||
| 		}  |         }  | ||||||
| 		else if (exp)  |         else if (exp)  | ||||||
| 		{ |         { | ||||||
| 			// Infinite
 |             // Infinite
 | ||||||
| 			return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; |             return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; | ||||||
| 		}  |         }  | ||||||
| 		else  |         else  | ||||||
| 		{ |         { | ||||||
| 			//Zero
 |             //Zero
 | ||||||
| 			return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; |             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) | inline void MatrixMul(int n, const float *a, const float *b, float *result) | ||||||
| { | { | ||||||
| 	for (int i = 0; i < n; ++i) |     for (int i = 0; i < n; ++i) | ||||||
| 	{ |     { | ||||||
| 		for (int j = 0; j < n; ++j) |         for (int j = 0; j < n; ++j) | ||||||
| 		{ |         { | ||||||
| 			float temp = 0; |             float temp = 0; | ||||||
| 			for (int k = 0; k < n; ++k) |             for (int k = 0; k < n; ++k) | ||||||
| 			{ |             { | ||||||
| 				temp += a[i * n + k] * b[k * n + j]; |                 temp += a[i * n + k] * b[k * n + j]; | ||||||
| 			} |             } | ||||||
| 			result[i * n + j] = temp; |             result[i * n + j] = temp; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Calculate sum of a float list
 | // Calculate sum of a float list
 | ||||||
| float MathFloatVectorSum(const std::vector<float>& Vec) | 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) | void Matrix33::LoadIdentity(Matrix33 &mtx) | ||||||
| { | { | ||||||
| 	memset(mtx.data, 0, sizeof(mtx.data)); |     memset(mtx.data, 0, sizeof(mtx.data)); | ||||||
| 	mtx.data[0] = 1.0f; |     mtx.data[0] = 1.0f; | ||||||
| 	mtx.data[4] = 1.0f; |     mtx.data[4] = 1.0f; | ||||||
| 	mtx.data[8] = 1.0f; |     mtx.data[8] = 1.0f; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Matrix33::RotateX(Matrix33 &mtx, float rad) | void Matrix33::RotateX(Matrix33 &mtx, float rad) | ||||||
| { | { | ||||||
| 	float s = sin(rad); |     float s = sin(rad); | ||||||
| 	float c = cos(rad); |     float c = cos(rad); | ||||||
| 	memset(mtx.data, 0, sizeof(mtx.data)); |     memset(mtx.data, 0, sizeof(mtx.data)); | ||||||
| 	mtx.data[0] = 1; |     mtx.data[0] = 1; | ||||||
| 	mtx.data[4] = c; |     mtx.data[4] = c; | ||||||
| 	mtx.data[5] = -s; |     mtx.data[5] = -s; | ||||||
| 	mtx.data[7] = s; |     mtx.data[7] = s; | ||||||
| 	mtx.data[8] = c; |     mtx.data[8] = c; | ||||||
| } | } | ||||||
| void Matrix33::RotateY(Matrix33 &mtx, float rad) | void Matrix33::RotateY(Matrix33 &mtx, float rad) | ||||||
| { | { | ||||||
| 	float s = sin(rad); |     float s = sin(rad); | ||||||
| 	float c = cos(rad); |     float c = cos(rad); | ||||||
| 	memset(mtx.data, 0, sizeof(mtx.data)); |     memset(mtx.data, 0, sizeof(mtx.data)); | ||||||
| 	mtx.data[0] = c; |     mtx.data[0] = c; | ||||||
| 	mtx.data[2] = s; |     mtx.data[2] = s; | ||||||
| 	mtx.data[4] = 1; |     mtx.data[4] = 1; | ||||||
| 	mtx.data[6] = -s;     |     mtx.data[6] = -s;     | ||||||
| 	mtx.data[8] = c; |     mtx.data[8] = c; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Matrix33::Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result) | 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]) | void Matrix33::Multiply(const Matrix33 &a, const float vec[3], float result[3]) | ||||||
| { | { | ||||||
| 	for (int i = 0; i < 3; ++i) { |     for (int i = 0; i < 3; ++i) { | ||||||
| 		result[i] = 0; |         result[i] = 0; | ||||||
| 		for (int k = 0; k < 3; ++k) { |         for (int k = 0; k < 3; ++k) { | ||||||
| 			result[i] += a.data[i * 3 + k] * vec[k]; |             result[i] += a.data[i * 3 + k] * vec[k]; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Matrix44::LoadIdentity(Matrix44 &mtx) | void Matrix44::LoadIdentity(Matrix44 &mtx) | ||||||
| { | { | ||||||
| 	memset(mtx.data, 0, sizeof(mtx.data)); |     memset(mtx.data, 0, sizeof(mtx.data)); | ||||||
| 	mtx.data[0] = 1.0f; |     mtx.data[0] = 1.0f; | ||||||
| 	mtx.data[5] = 1.0f; |     mtx.data[5] = 1.0f; | ||||||
| 	mtx.data[10] = 1.0f; |     mtx.data[10] = 1.0f; | ||||||
| 	mtx.data[15] = 1.0f; |     mtx.data[15] = 1.0f; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Matrix44::LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33) | void Matrix44::LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33) | ||||||
| { | { | ||||||
| 	for (int i = 0; i < 3; ++i) |     for (int i = 0; i < 3; ++i) | ||||||
| 	{ |     { | ||||||
| 		for (int j = 0; j < 3; ++j) |         for (int j = 0; j < 3; ++j) | ||||||
| 		{ |         { | ||||||
| 			mtx.data[i * 4 + j] = m33.data[i * 3 + j]; |             mtx.data[i * 4 + j] = m33.data[i * 3 + j]; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	for (int i = 0; i < 3; ++i) |     for (int i = 0; i < 3; ++i) | ||||||
| 	{ |     { | ||||||
| 		mtx.data[i * 4 + 3] = 0; |         mtx.data[i * 4 + 3] = 0; | ||||||
| 		mtx.data[i + 12] = 0; |         mtx.data[i + 12] = 0; | ||||||
| 	} |     } | ||||||
| 	mtx.data[15] = 1.0f; |     mtx.data[15] = 1.0f; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Matrix44::Set(Matrix44 &mtx, const float mtxArray[16]) | void Matrix44::Set(Matrix44 &mtx, const float mtxArray[16]) | ||||||
| { | { | ||||||
| 	for(int i = 0; i < 16; ++i) { |     for(int i = 0; i < 16; ++i) { | ||||||
| 		mtx.data[i] = mtxArray[i]; |         mtx.data[i] = mtxArray[i]; | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Matrix44::Translate(Matrix44 &mtx, const float vec[3]) | void Matrix44::Translate(Matrix44 &mtx, const float vec[3]) | ||||||
| { | { | ||||||
| 	LoadIdentity(mtx); |     LoadIdentity(mtx); | ||||||
| 	mtx.data[3] = vec[0]; |     mtx.data[3] = vec[0]; | ||||||
| 	mtx.data[7] = vec[1]; |     mtx.data[7] = vec[1]; | ||||||
| 	mtx.data[11] = vec[2]; |     mtx.data[11] = vec[2]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Matrix44::Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result) | 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, | static const u64 DOUBLE_SIGN = 0x8000000000000000ULL, | ||||||
| 	DOUBLE_EXP  = 0x7FF0000000000000ULL, |     DOUBLE_EXP  = 0x7FF0000000000000ULL, | ||||||
| 	DOUBLE_FRAC = 0x000FFFFFFFFFFFFFULL, |     DOUBLE_FRAC = 0x000FFFFFFFFFFFFFULL, | ||||||
| 	DOUBLE_ZERO = 0x0000000000000000ULL; |     DOUBLE_ZERO = 0x0000000000000000ULL; | ||||||
| 
 | 
 | ||||||
| static const u32 FLOAT_SIGN = 0x80000000, | static const u32 FLOAT_SIGN = 0x80000000, | ||||||
| 	FLOAT_EXP  = 0x7F800000, |     FLOAT_EXP  = 0x7F800000, | ||||||
| 	FLOAT_FRAC = 0x007FFFFF, |     FLOAT_FRAC = 0x007FFFFF, | ||||||
| 	FLOAT_ZERO = 0x00000000; |     FLOAT_ZERO = 0x00000000; | ||||||
| 
 | 
 | ||||||
| union IntDouble { | union IntDouble { | ||||||
| 	double d; |     double d; | ||||||
| 	u64 i; |     u64 i; | ||||||
| }; | }; | ||||||
| union IntFloat { | union IntFloat { | ||||||
| 	float f; |     float f; | ||||||
| 	u32 i; |     u32 i; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| inline bool IsNAN(double d) | inline bool IsNAN(double d) | ||||||
| { | { | ||||||
| 	IntDouble x; x.d = d; |     IntDouble x; x.d = d; | ||||||
| 	return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && |     return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | ||||||
| 			 ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) ); |              ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline bool IsQNAN(double d) | inline bool IsQNAN(double d) | ||||||
| { | { | ||||||
| 	IntDouble x; x.d = d; |     IntDouble x; x.d = d; | ||||||
| 	return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && |     return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | ||||||
| 		     ((x.i & 0x0007fffffffffffULL) == 0x000000000000000ULL) && |              ((x.i & 0x0007fffffffffffULL) == 0x000000000000000ULL) && | ||||||
| 		     ((x.i & 0x000800000000000ULL) == 0x000800000000000ULL) ); |              ((x.i & 0x000800000000000ULL) == 0x000800000000000ULL) ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline bool IsSNAN(double d) | inline bool IsSNAN(double d) | ||||||
| { | { | ||||||
| 	IntDouble x; x.d = d; |     IntDouble x; x.d = d; | ||||||
| 	return( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && |     return( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | ||||||
| 			((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) && |             ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) && | ||||||
| 			((x.i & 0x0008000000000000ULL) == DOUBLE_ZERO) ); |             ((x.i & 0x0008000000000000ULL) == DOUBLE_ZERO) ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline float FlushToZero(float f) | inline float FlushToZero(float f) | ||||||
| { | { | ||||||
| 	IntFloat x; x.f = f; |     IntFloat x; x.f = f; | ||||||
| 	if ((x.i & FLOAT_EXP) == 0) |     if ((x.i & FLOAT_EXP) == 0) | ||||||
| 		x.i &= FLOAT_SIGN;  // turn into signed zero
 |         x.i &= FLOAT_SIGN;  // turn into signed zero
 | ||||||
| 	return x.f; |     return x.f; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline double FlushToZeroAsFloat(double d) | inline double FlushToZeroAsFloat(double d) | ||||||
| { | { | ||||||
| 	IntDouble x; x.d = d; |     IntDouble x; x.d = d; | ||||||
| 	if ((x.i & DOUBLE_EXP) < 0x3800000000000000ULL) |     if ((x.i & DOUBLE_EXP) < 0x3800000000000000ULL) | ||||||
| 		x.i &= DOUBLE_SIGN;  // turn into signed zero
 |         x.i &= DOUBLE_SIGN;  // turn into signed zero
 | ||||||
| 	return x.d; |     return x.d; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| enum PPCFpClass | enum PPCFpClass | ||||||
| { | { | ||||||
| 	PPC_FPCLASS_QNAN = 0x11, |     PPC_FPCLASS_QNAN = 0x11, | ||||||
| 	PPC_FPCLASS_NINF = 0x9, |     PPC_FPCLASS_NINF = 0x9, | ||||||
| 	PPC_FPCLASS_NN   = 0x8, |     PPC_FPCLASS_NN   = 0x8, | ||||||
| 	PPC_FPCLASS_ND   = 0x18, |     PPC_FPCLASS_ND   = 0x18, | ||||||
| 	PPC_FPCLASS_NZ   = 0x12, |     PPC_FPCLASS_NZ   = 0x12, | ||||||
| 	PPC_FPCLASS_PZ   = 0x2, |     PPC_FPCLASS_PZ   = 0x2, | ||||||
| 	PPC_FPCLASS_PD   = 0x14, |     PPC_FPCLASS_PD   = 0x14, | ||||||
| 	PPC_FPCLASS_PN   = 0x4, |     PPC_FPCLASS_PN   = 0x4, | ||||||
| 	PPC_FPCLASS_PINF = 0x5, |     PPC_FPCLASS_PINF = 0x5, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Uses PowerPC conventions for the return value, so it can be easily
 | // Uses PowerPC conventions for the return value, so it can be easily
 | ||||||
|  | @ -93,42 +93,42 @@ u32 ClassifyFloat(float fvalue); | ||||||
| template<class T> | template<class T> | ||||||
| struct Rectangle | struct Rectangle | ||||||
| { | { | ||||||
| 	T left; |     T left; | ||||||
| 	T top; |     T top; | ||||||
| 	T right; |     T right; | ||||||
| 	T bottom; |     T bottom; | ||||||
| 
 | 
 | ||||||
| 	Rectangle() |     Rectangle() | ||||||
| 	{ } |     { } | ||||||
| 
 | 
 | ||||||
| 	Rectangle(T theLeft, T theTop, T theRight, T theBottom) |     Rectangle(T theLeft, T theTop, T theRight, T theBottom) | ||||||
| 		: left(theLeft), top(theTop), right(theRight), bottom(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; } |     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 GetWidth() const { return abs(right - left); } | ||||||
| 	T GetHeight() const { return abs(bottom - top); } |     T GetHeight() const { return abs(bottom - top); } | ||||||
| 
 | 
 | ||||||
| 	// If the rectangle is in a coordinate system with a lower-left origin, use
 |     // If the rectangle is in a coordinate system with a lower-left origin, use
 | ||||||
| 	// this Clamp.
 |     // this Clamp.
 | ||||||
| 	void ClampLL(T x1, T y1, T x2, T y2) |     void ClampLL(T x1, T y1, T x2, T y2) | ||||||
| 	{ |     { | ||||||
| 		if (left < x1) left = x1; |         if (left < x1) left = x1; | ||||||
| 		if (right > x2) right = x2; |         if (right > x2) right = x2; | ||||||
| 		if (top > y1) top = y1; |         if (top > y1) top = y1; | ||||||
| 		if (bottom < y2) bottom = y2; |         if (bottom < y2) bottom = y2; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// If the rectangle is in a coordinate system with an upper-left origin,
 |     // If the rectangle is in a coordinate system with an upper-left origin,
 | ||||||
| 	// use this Clamp.
 |     // use this Clamp.
 | ||||||
| 	void ClampUL(T x1, T y1, T x2, T y2)  |     void ClampUL(T x1, T y1, T x2, T y2)  | ||||||
| 	{ |     { | ||||||
| 		if (left < x1) left = x1; |         if (left < x1) left = x1; | ||||||
| 		if (right > x2) right = x2; |         if (right > x2) right = x2; | ||||||
| 		if (top < y1) top = y1; |         if (top < y1) top = y1; | ||||||
| 		if (bottom > y2) bottom = y2; |         if (bottom > y2) bottom = y2; | ||||||
| 	} |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| }  // namespace MathUtil
 | }  // namespace MathUtil
 | ||||||
|  | @ -138,28 +138,28 @@ inline double pow2(double x) {return x * x;} | ||||||
| 
 | 
 | ||||||
| float MathFloatVectorSum(const std::vector<float>&); | float MathFloatVectorSum(const std::vector<float>&); | ||||||
| 
 | 
 | ||||||
| #define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1)) | #define ROUND_UP(x, a)        (((x) + (a) - 1) & ~((a) - 1)) | ||||||
| #define ROUND_DOWN(x, a)	((x) & ~((a) - 1)) | #define ROUND_DOWN(x, a)    ((x) & ~((a) - 1)) | ||||||
| 
 | 
 | ||||||
| // Rounds down. 0 -> undefined
 | // Rounds down. 0 -> undefined
 | ||||||
| inline u64 Log2(u64 val) | inline u64 Log2(u64 val) | ||||||
| { | { | ||||||
| #if defined(__GNUC__) | #if defined(__GNUC__) | ||||||
| 	return 63 - __builtin_clzll(val); |     return 63 - __builtin_clzll(val); | ||||||
| 
 | 
 | ||||||
| #elif defined(_MSC_VER) && defined(_M_X64) | #elif defined(_MSC_VER) && defined(_M_X64) | ||||||
| 	unsigned long result = -1; |     unsigned long result = -1; | ||||||
| 	_BitScanReverse64(&result, val); |     _BitScanReverse64(&result, val); | ||||||
| 	return result; |     return result; | ||||||
| 
 | 
 | ||||||
| #else | #else | ||||||
| 	u64 result = -1; |     u64 result = -1; | ||||||
| 	while (val != 0) |     while (val != 0) | ||||||
| 	{ |     { | ||||||
| 		val >>= 1; |         val >>= 1; | ||||||
| 		++result; |         ++result; | ||||||
| 	} |     } | ||||||
| 	return result; |     return result; | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -169,32 +169,32 @@ inline u64 Log2(u64 val) | ||||||
| class Matrix33 | class Matrix33 | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	static void LoadIdentity(Matrix33 &mtx); |     static void LoadIdentity(Matrix33 &mtx); | ||||||
| 
 | 
 | ||||||
| 	// set mtx to be a rotation matrix around the x axis
 |     // set mtx to be a rotation matrix around the x axis
 | ||||||
| 	static void RotateX(Matrix33 &mtx, float rad); |     static void RotateX(Matrix33 &mtx, float rad); | ||||||
| 	// set mtx to be a rotation matrix around the y axis
 |     // set mtx to be a rotation matrix around the y axis
 | ||||||
| 	static void RotateY(Matrix33 &mtx, float rad); |     static void RotateY(Matrix33 &mtx, float rad); | ||||||
| 
 | 
 | ||||||
| 	// set result = a x b
 |     // set result = a x b
 | ||||||
| 	static void Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result); |     static void Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result); | ||||||
| 	static void Multiply(const Matrix33 &a, const float vec[3], float result[3]); |     static void Multiply(const Matrix33 &a, const float vec[3], float result[3]); | ||||||
| 
 | 
 | ||||||
| 	float data[9]; |     float data[9]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class Matrix44 | class Matrix44 | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	static void LoadIdentity(Matrix44 &mtx); |     static void LoadIdentity(Matrix44 &mtx); | ||||||
| 	static void LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33); |     static void LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33); | ||||||
| 	static void Set(Matrix44 &mtx, const float mtxArray[16]); |     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_
 | #endif // _MATH_UTIL_H_
 | ||||||
|  |  | ||||||
|  | @ -27,148 +27,148 @@ | ||||||
| void* AllocateExecutableMemory(size_t size, bool low) | void* AllocateExecutableMemory(size_t size, bool low) | ||||||
| { | { | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| 	void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); |     void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); | ||||||
| #else | #else | ||||||
| 	static char *map_hint = 0; |     static char *map_hint = 0; | ||||||
| #if defined(__x86_64__) && !defined(MAP_32BIT) | #if defined(__x86_64__) && !defined(MAP_32BIT) | ||||||
| 	// This OS has no flag to enforce allocation below the 4 GB boundary,
 |     // 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
 |     // but if we hint that we want a low address it is very likely we will
 | ||||||
| 	// get one.
 |     // get one.
 | ||||||
| 	// An older version of this code used MAP_FIXED, but that has the side
 |     // 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
 |     // effect of discarding already mapped pages that happen to be in the
 | ||||||
| 	// requested virtual memory range (such as the emulated RAM, sometimes).
 |     // requested virtual memory range (such as the emulated RAM, sometimes).
 | ||||||
| 	if (low && (!map_hint)) |     if (low && (!map_hint)) | ||||||
| 		map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */ |         map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */ | ||||||
| #endif | #endif | ||||||
| 	void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, |     void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, | ||||||
| 		MAP_ANON | MAP_PRIVATE |         MAP_ANON | MAP_PRIVATE | ||||||
| #if defined(__x86_64__) && defined(MAP_32BIT) | #if defined(__x86_64__) && defined(MAP_32BIT) | ||||||
| 		| (low ? MAP_32BIT : 0) |         | (low ? MAP_32BIT : 0) | ||||||
| #endif | #endif | ||||||
| 		, -1, 0); |         , -1, 0); | ||||||
| #endif /* defined(_WIN32) */ | #endif /* defined(_WIN32) */ | ||||||
| 
 | 
 | ||||||
| 	// printf("Mapped executable memory at %p (size %ld)\n", ptr,
 |     // printf("Mapped executable memory at %p (size %ld)\n", ptr,
 | ||||||
| 	//	(unsigned long)size);
 |     //    (unsigned long)size);
 | ||||||
|      |      | ||||||
| #if defined(__FreeBSD__) | #if defined(__FreeBSD__) | ||||||
| 	if (ptr == MAP_FAILED) |     if (ptr == MAP_FAILED) | ||||||
| 	{ |     { | ||||||
| 		ptr = NULL; |         ptr = NULL; | ||||||
| #else | #else | ||||||
| 	if (ptr == NULL) |     if (ptr == NULL) | ||||||
| 	{ |     { | ||||||
| #endif     | #endif     | ||||||
| 		PanicAlert("Failed to allocate executable memory"); |         PanicAlert("Failed to allocate executable memory"); | ||||||
| 	} |     } | ||||||
| #if !defined(_WIN32) && defined(__x86_64__) && !defined(MAP_32BIT) | #if !defined(_WIN32) && defined(__x86_64__) && !defined(MAP_32BIT) | ||||||
| 	else |     else | ||||||
| 	{ |     { | ||||||
| 		if (low) |         if (low) | ||||||
| 		{ |         { | ||||||
| 			map_hint += size; |             map_hint += size; | ||||||
| 			map_hint = (char*)round_page(map_hint); /* round up to the next page */ |             map_hint = (char*)round_page(map_hint); /* round up to the next page */ | ||||||
| 			// printf("Next map will (hopefully) be at %p\n", map_hint);
 |             // printf("Next map will (hopefully) be at %p\n", map_hint);
 | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #if defined(_M_X64) | #if defined(_M_X64) | ||||||
| 	if ((u64)ptr >= 0x80000000 && low == true) |     if ((u64)ptr >= 0x80000000 && low == true) | ||||||
| 		PanicAlert("Executable memory ended up above 2GB!"); |         PanicAlert("Executable memory ended up above 2GB!"); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	return ptr; |     return ptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void* AllocateMemoryPages(size_t size) | void* AllocateMemoryPages(size_t size) | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); |     void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); | ||||||
| #else | #else | ||||||
| 	void* ptr = mmap(0, size, PROT_READ | PROT_WRITE, |     void* ptr = mmap(0, size, PROT_READ | PROT_WRITE, | ||||||
| 			MAP_ANON | MAP_PRIVATE, -1, 0); |             MAP_ANON | MAP_PRIVATE, -1, 0); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	// printf("Mapped memory at %p (size %ld)\n", ptr,
 |     // printf("Mapped memory at %p (size %ld)\n", ptr,
 | ||||||
| 	//	(unsigned long)size);
 |     //    (unsigned long)size);
 | ||||||
| 
 | 
 | ||||||
| 	if (ptr == NULL) |     if (ptr == NULL) | ||||||
| 		PanicAlert("Failed to allocate raw memory"); |         PanicAlert("Failed to allocate raw memory"); | ||||||
| 
 | 
 | ||||||
| 	return ptr; |     return ptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void* AllocateAlignedMemory(size_t size,size_t alignment) | void* AllocateAlignedMemory(size_t size,size_t alignment) | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	void* ptr =  _aligned_malloc(size,alignment); |     void* ptr =  _aligned_malloc(size,alignment); | ||||||
| #else | #else | ||||||
| 	void* ptr = NULL; |     void* ptr = NULL; | ||||||
| #ifdef ANDROID | #ifdef ANDROID | ||||||
| 	ptr = memalign(alignment, size); |     ptr = memalign(alignment, size); | ||||||
| #else | #else | ||||||
| 	if (posix_memalign(&ptr, alignment, size) != 0) |     if (posix_memalign(&ptr, alignment, size) != 0) | ||||||
| 		ERROR_LOG(MEMMAP, "Failed to allocate aligned memory"); |         ERROR_LOG(MEMMAP, "Failed to allocate aligned memory"); | ||||||
| #endif | #endif | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	// printf("Mapped memory at %p (size %ld)\n", ptr,
 |     // printf("Mapped memory at %p (size %ld)\n", ptr,
 | ||||||
| 	//	(unsigned long)size);
 |     //    (unsigned long)size);
 | ||||||
| 
 | 
 | ||||||
| 	if (ptr == NULL) |     if (ptr == NULL) | ||||||
| 		PanicAlert("Failed to allocate aligned memory"); |         PanicAlert("Failed to allocate aligned memory"); | ||||||
| 
 | 
 | ||||||
| 	return ptr; |     return ptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void FreeMemoryPages(void* ptr, size_t size) | void FreeMemoryPages(void* ptr, size_t size) | ||||||
| { | { | ||||||
| 	if (ptr) |     if (ptr) | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
|      |      | ||||||
| 		if (!VirtualFree(ptr, 0, MEM_RELEASE)) |         if (!VirtualFree(ptr, 0, MEM_RELEASE)) | ||||||
| 			PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg()); |             PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg()); | ||||||
| 		ptr = NULL; // Is this our responsibility?
 |         ptr = NULL; // Is this our responsibility?
 | ||||||
|      |      | ||||||
| #else | #else | ||||||
| 		munmap(ptr, size); |         munmap(ptr, size); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void FreeAlignedMemory(void* ptr) | void FreeAlignedMemory(void* ptr) | ||||||
| { | { | ||||||
| 	if (ptr) |     if (ptr) | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	_aligned_free(ptr); |     _aligned_free(ptr); | ||||||
| #else | #else | ||||||
| 	free(ptr); |     free(ptr); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) | void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	DWORD oldValue; |     DWORD oldValue; | ||||||
| 	if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue)) |     if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue)) | ||||||
| 		PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg()); |         PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg()); | ||||||
| #else | #else | ||||||
| 	mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ); |     mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) | void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	DWORD oldValue; |     DWORD oldValue; | ||||||
| 	if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue)) |     if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue)) | ||||||
| 		PanicAlert("UnWriteProtectMemory failed!\n%s", GetLastErrorMsg()); |         PanicAlert("UnWriteProtectMemory failed!\n%s", GetLastErrorMsg()); | ||||||
| #else | #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 | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -176,22 +176,22 @@ std::string MemUsage() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| #pragma comment(lib, "psapi") | #pragma comment(lib, "psapi") | ||||||
| 	DWORD processID = GetCurrentProcessId(); |     DWORD processID = GetCurrentProcessId(); | ||||||
| 	HANDLE hProcess; |     HANDLE hProcess; | ||||||
| 	PROCESS_MEMORY_COUNTERS pmc; |     PROCESS_MEMORY_COUNTERS pmc; | ||||||
| 	std::string Ret; |     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); |     hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); | ||||||
| 	if (NULL == hProcess) return "MemUsage Error"; |     if (NULL == hProcess) return "MemUsage Error"; | ||||||
| 
 | 
 | ||||||
| 	if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) |     if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) | ||||||
| 		Ret = StringFromFormat("%s K", ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); |         Ret = StringFromFormat("%s K", ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); | ||||||
| 
 | 
 | ||||||
| 	CloseHandle(hProcess); |     CloseHandle(hProcess); | ||||||
| 	return Ret; |     return Ret; | ||||||
| #else | #else | ||||||
| 	return ""; |     return ""; | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -18,20 +18,20 @@ | ||||||
| // This function might change the error code.
 | // This function might change the error code.
 | ||||||
| const char* GetLastErrorMsg() | const char* GetLastErrorMsg() | ||||||
| { | { | ||||||
| 	static const size_t buff_size = 255; |     static const size_t buff_size = 255; | ||||||
| 
 | 
 | ||||||
| #ifdef _WIN32 | #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(), |     FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), | ||||||
| 		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||||||
| 		err_str, buff_size, NULL); |         err_str, buff_size, NULL); | ||||||
| #else | #else | ||||||
| 	static __thread char err_str[buff_size] = {}; |     static __thread char err_str[buff_size] = {}; | ||||||
| 
 | 
 | ||||||
| 	// Thread safe (XSI-compliant)
 |     // Thread safe (XSI-compliant)
 | ||||||
| 	strerror_r(errno, err_str, buff_size); |     strerror_r(errno, err_str, buff_size); | ||||||
| #endif | #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
 | // wxWidgets is enabled we will use wxMsgAlert() that is defined in Main.cpp
 | ||||||
| void RegisterMsgAlertHandler(MsgAlertHandler handler) | void RegisterMsgAlertHandler(MsgAlertHandler handler) | ||||||
| { | { | ||||||
| 	msg_handler = handler; |     msg_handler = handler; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Select translation function.  For wxWidgets use wxStringTranslator in Main.cpp
 | // Select translation function.  For wxWidgets use wxStringTranslator in Main.cpp
 | ||||||
| void RegisterStringTranslator(StringTranslator translator) | void RegisterStringTranslator(StringTranslator translator) | ||||||
| { | { | ||||||
| 	str_translator = translator; |     str_translator = translator; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // enable/disable the alert handler
 | // enable/disable the alert handler
 | ||||||
| void SetEnableAlert(bool enable) | void SetEnableAlert(bool enable) | ||||||
| { | { | ||||||
| 	AlertEnabled = enable; |     AlertEnabled = enable; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // This is the first stop for gui alerts where the log is updated and the
 | // This is the first stop for gui alerts where the log is updated and the
 | ||||||
| // correct window is shown
 | // correct window is shown
 | ||||||
| bool MsgAlert(bool yes_no, int Style, const char* format, ...) | bool MsgAlert(bool yes_no, int Style, const char* format, ...) | ||||||
| { | { | ||||||
| 	// Read message and write it to the log
 |     // Read message and write it to the log
 | ||||||
| 	std::string caption; |     std::string caption; | ||||||
| 	char buffer[2048]; |     char buffer[2048]; | ||||||
| 
 | 
 | ||||||
| 	static std::string info_caption; |     static std::string info_caption; | ||||||
| 	static std::string warn_caption; |     static std::string warn_caption; | ||||||
| 	static std::string ques_caption; |     static std::string ques_caption; | ||||||
| 	static std::string crit_caption; |     static std::string crit_caption; | ||||||
| 
 | 
 | ||||||
| 	if (!info_caption.length()) |     if (!info_caption.length()) | ||||||
| 	{ |     { | ||||||
| 		info_caption = str_translator(_trans("Information")); |         info_caption = str_translator(_trans("Information")); | ||||||
| 		ques_caption = str_translator(_trans("Question")); |         ques_caption = str_translator(_trans("Question")); | ||||||
| 		warn_caption = str_translator(_trans("Warning")); |         warn_caption = str_translator(_trans("Warning")); | ||||||
| 		crit_caption = str_translator(_trans("Critical")); |         crit_caption = str_translator(_trans("Critical")); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	switch(Style) |     switch(Style) | ||||||
| 	{ |     { | ||||||
| 		case INFORMATION: |         case INFORMATION: | ||||||
| 			caption = info_caption; |             caption = info_caption; | ||||||
| 			break; |             break; | ||||||
| 		case QUESTION: |         case QUESTION: | ||||||
| 			caption = ques_caption; |             caption = ques_caption; | ||||||
| 			break; |             break; | ||||||
| 		case WARNING: |         case WARNING: | ||||||
| 			caption = warn_caption; |             caption = warn_caption; | ||||||
| 			break; |             break; | ||||||
| 		case CRITICAL: |         case CRITICAL: | ||||||
| 			caption = crit_caption; |             caption = crit_caption; | ||||||
| 			break; |             break; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	va_list args; |     va_list args; | ||||||
| 	va_start(args, format); |     va_start(args, format); | ||||||
| 	CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args); |     CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args); | ||||||
| 	va_end(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
 |     // Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored
 | ||||||
| 	if (msg_handler && (AlertEnabled || Style == QUESTION || Style == CRITICAL)) |     if (msg_handler && (AlertEnabled || Style == QUESTION || Style == CRITICAL)) | ||||||
| 		return msg_handler(caption.c_str(), buffer, yes_no, Style); |         return msg_handler(caption.c_str(), buffer, yes_no, Style); | ||||||
| 
 | 
 | ||||||
| 	return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Default non library dependent panic alert
 | // Default non library dependent panic alert
 | ||||||
| bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style) | bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style) | ||||||
| { | { | ||||||
| //#ifdef _WIN32
 | //#ifdef _WIN32
 | ||||||
| //	int STYLE = MB_ICONINFORMATION;
 | //    int STYLE = MB_ICONINFORMATION;
 | ||||||
| //	if (Style == QUESTION) STYLE = MB_ICONQUESTION;
 | //    if (Style == QUESTION) STYLE = MB_ICONQUESTION;
 | ||||||
| //	if (Style == WARNING) STYLE = MB_ICONWARNING;
 | //    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
 | //#else
 | ||||||
| 	printf("%s\n", text); |     printf("%s\n", text); | ||||||
| 	return true; |     return true; | ||||||
| //#endif
 | //#endif
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Default (non) translator
 | // Default (non) translator
 | ||||||
| std::string DefaultStringTranslator(const char* text) | std::string DefaultStringTranslator(const char* text) | ||||||
| { | { | ||||||
| 	return text; |     return text; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,10 +10,10 @@ | ||||||
| // Message alerts
 | // Message alerts
 | ||||||
| enum MSG_TYPE | enum MSG_TYPE | ||||||
| { | { | ||||||
| 	INFORMATION, |     INFORMATION, | ||||||
| 	QUESTION, |     QUESTION, | ||||||
| 	WARNING, |     WARNING, | ||||||
| 	CRITICAL |     CRITICAL | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef bool (*MsgAlertHandler)(const char* caption, const char* text,  | 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, ...) | extern bool MsgAlert(bool yes_no, int Style, const char* format, ...) | ||||||
| #ifdef __GNUC__ | #ifdef __GNUC__ | ||||||
| 	__attribute__((format(printf, 3, 4))) |     __attribute__((format(printf, 3, 4))) | ||||||
| #endif | #endif | ||||||
| 	; |     ; | ||||||
| void SetEnableAlert(bool enable); | void SetEnableAlert(bool enable); | ||||||
| 
 | 
 | ||||||
| #ifndef GEKKO | #ifndef GEKKO | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	#define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__)  |     #define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__)  | ||||||
| 	#define PanicAlert(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__)  |     #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__)  | ||||||
| 	#define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__)  |     #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__)  | ||||||
| 	#define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__)  |     #define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__)  | ||||||
| 	#define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, 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.
 |     // Use these macros (that do the same thing) if the message should be translated.
 | ||||||
| 	#define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__)  |     #define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__)  | ||||||
| 	#define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__)  |     #define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__)  | ||||||
| 	#define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__)  |     #define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__)  | ||||||
| 	#define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__)  |     #define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__)  | ||||||
| 	#define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__)  |     #define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__)  | ||||||
| #else | #else | ||||||
| 	#define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__)  |     #define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__)  | ||||||
| 	#define PanicAlert(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__)  |     #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__)  | ||||||
| 	#define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__)  |     #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__)  | ||||||
| 	#define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__)  |     #define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__)  | ||||||
| 	#define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, 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.
 |     // Use these macros (that do the same thing) if the message should be translated.
 | ||||||
| 	#define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__)  |     #define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__)  | ||||||
| 	#define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__)  |     #define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__)  | ||||||
| 	#define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__)  |     #define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__)  | ||||||
| 	#define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__)  |     #define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__)  | ||||||
| 	#define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__)  |     #define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__)  | ||||||
| #endif | #endif | ||||||
| #else | #else | ||||||
| // GEKKO
 | // GEKKO
 | ||||||
| 	#define SuccessAlert(format, ...) ; |     #define SuccessAlert(format, ...) ; | ||||||
| 	#define PanicAlert(format, ...) ; |     #define PanicAlert(format, ...) ; | ||||||
| 	#define PanicYesNo(format, ...) ; |     #define PanicYesNo(format, ...) ; | ||||||
| 	#define AskYesNo(format, ...) ; |     #define AskYesNo(format, ...) ; | ||||||
| 	#define CriticalAlert(format, ...) ; |     #define CriticalAlert(format, ...) ; | ||||||
| 	#define SuccessAlertT(format, ...) ; |     #define SuccessAlertT(format, ...) ; | ||||||
| 	#define PanicAlertT(format, ...) ; |     #define PanicAlertT(format, ...) ; | ||||||
| 	#define PanicYesNoT(format, ...) ; |     #define PanicYesNoT(format, ...) ; | ||||||
| 	#define AskYesNoT(format, ...) ; |     #define AskYesNoT(format, ...) ; | ||||||
| 	#define CriticalAlertT(format, ...) ; |     #define CriticalAlertT(format, ...) ; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #endif // _MSGHANDLER_H_
 | #endif // _MSGHANDLER_H_
 | ||||||
|  |  | ||||||
|  | @ -76,9 +76,9 @@ | ||||||
| #define EMU_FASTCALL __fastcall | #define EMU_FASTCALL __fastcall | ||||||
| 
 | 
 | ||||||
| inline struct tm* localtime_r(const time_t *clock, struct tm *result) { | inline struct tm* localtime_r(const time_t *clock, struct tm *result) { | ||||||
| 	if (localtime_s(result, clock) == 0) |     if (localtime_s(result, clock) == 0) | ||||||
| 		return result; |         return result; | ||||||
| 	return NULL; |     return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #else | #else | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| #ifndef CONDITION_VARIABLE_H_ | #ifndef CONDITION_VARIABLE_H_ | ||||||
| #define 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__) | #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) | ||||||
| 
 | 
 | ||||||
| #ifndef __has_include | #ifndef __has_include | ||||||
|  | @ -47,121 +47,121 @@ namespace std | ||||||
| class condition_variable | class condition_variable | ||||||
| { | { | ||||||
| #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | ||||||
| 	typedef CONDITION_VARIABLE native_type; |     typedef CONDITION_VARIABLE native_type; | ||||||
| #elif defined(_WIN32) | #elif defined(_WIN32) | ||||||
| 	typedef HANDLE native_type; |     typedef HANDLE native_type; | ||||||
| #else | #else | ||||||
| 	typedef pthread_cond_t native_type; |     typedef pthread_cond_t native_type; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
| 
 | 
 | ||||||
| #ifdef USE_EVENTS | #ifdef USE_EVENTS | ||||||
| 	typedef native_type native_handle_type; |     typedef native_type native_handle_type; | ||||||
| #else | #else | ||||||
| 	typedef native_type* native_handle_type; |     typedef native_type* native_handle_type; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	condition_variable() |     condition_variable() | ||||||
| 	{ |     { | ||||||
| #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | ||||||
| 		InitializeConditionVariable(&m_handle); |         InitializeConditionVariable(&m_handle); | ||||||
| #elif defined(_WIN32) | #elif defined(_WIN32) | ||||||
| 		m_handle = CreateEvent(NULL, false, false, NULL); |         m_handle = CreateEvent(NULL, false, false, NULL); | ||||||
| #else | #else | ||||||
| 		pthread_cond_init(&m_handle, NULL); |         pthread_cond_init(&m_handle, NULL); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	~condition_variable() |     ~condition_variable() | ||||||
| 	{ |     { | ||||||
| #if defined(_WIN32) && !defined(USE_CONDITION_VARIABLES) | #if defined(_WIN32) && !defined(USE_CONDITION_VARIABLES) | ||||||
| 		CloseHandle(m_handle); |         CloseHandle(m_handle); | ||||||
| #elif !defined(_WIN32) | #elif !defined(_WIN32) | ||||||
| 		pthread_cond_destroy(&m_handle); |         pthread_cond_destroy(&m_handle); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	condition_variable(const condition_variable&) /*= delete*/; |     condition_variable(const condition_variable&) /*= delete*/; | ||||||
| 	condition_variable& operator=(const condition_variable&) /*= delete*/; |     condition_variable& operator=(const condition_variable&) /*= delete*/; | ||||||
| 
 | 
 | ||||||
| 	void notify_one() |     void notify_one() | ||||||
| 	{ |     { | ||||||
| #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | ||||||
| 		WakeConditionVariable(&m_handle); |         WakeConditionVariable(&m_handle); | ||||||
| #elif defined(_WIN32) | #elif defined(_WIN32) | ||||||
| 		SetEvent(m_handle); |         SetEvent(m_handle); | ||||||
| #else | #else | ||||||
| 		pthread_cond_signal(&m_handle); |         pthread_cond_signal(&m_handle); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void notify_all() |     void notify_all() | ||||||
| 	{ |     { | ||||||
| #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | ||||||
| 		WakeAllConditionVariable(&m_handle); |         WakeAllConditionVariable(&m_handle); | ||||||
| #elif defined(_WIN32) | #elif defined(_WIN32) | ||||||
| 		// TODO: broken
 |         // TODO: broken
 | ||||||
| 		SetEvent(m_handle); |         SetEvent(m_handle); | ||||||
| #else | #else | ||||||
| 		pthread_cond_broadcast(&m_handle); |         pthread_cond_broadcast(&m_handle); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void wait(unique_lock<mutex>& lock) |     void wait(unique_lock<mutex>& lock) | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	#ifdef USE_SRWLOCKS |     #ifdef USE_SRWLOCKS | ||||||
| 		SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0); |         SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0); | ||||||
| 	#elif defined(USE_CONDITION_VARIABLES) |     #elif defined(USE_CONDITION_VARIABLES) | ||||||
| 		SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE); |         SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE); | ||||||
| 	#else |     #else | ||||||
| 		// TODO: broken, the unlock and wait need to be atomic
 |         // TODO: broken, the unlock and wait need to be atomic
 | ||||||
| 		lock.unlock(); |         lock.unlock(); | ||||||
| 		WaitForSingleObject(m_handle, INFINITE); |         WaitForSingleObject(m_handle, INFINITE); | ||||||
| 		lock.lock(); |         lock.lock(); | ||||||
| 	#endif |     #endif | ||||||
| #else | #else | ||||||
| 		pthread_cond_wait(&m_handle, lock.mutex()->native_handle()); |         pthread_cond_wait(&m_handle, lock.mutex()->native_handle()); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	template <class Predicate> |     template <class Predicate> | ||||||
| 	void wait(unique_lock<mutex>& lock, Predicate pred) |     void wait(unique_lock<mutex>& lock, Predicate pred) | ||||||
| 	{ |     { | ||||||
| 		while (!pred()) |         while (!pred()) | ||||||
| 			wait(lock); |             wait(lock); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	//template <class Clock, class Duration>
 |     //template <class Clock, class Duration>
 | ||||||
| 	//cv_status wait_until(unique_lock<mutex>& lock,
 |     //cv_status wait_until(unique_lock<mutex>& lock,
 | ||||||
| 	//	const chrono::time_point<Clock, Duration>& abs_time);
 |     //    const chrono::time_point<Clock, Duration>& abs_time);
 | ||||||
| 
 | 
 | ||||||
| 	//template <class Clock, class Duration, class Predicate>
 |     //template <class Clock, class Duration, class Predicate>
 | ||||||
| 	//	bool wait_until(unique_lock<mutex>& lock,
 |     //    bool wait_until(unique_lock<mutex>& lock,
 | ||||||
| 	//	const chrono::time_point<Clock, Duration>& abs_time,
 |     //    const chrono::time_point<Clock, Duration>& abs_time,
 | ||||||
| 	//	Predicate pred);
 |     //    Predicate pred);
 | ||||||
| 
 | 
 | ||||||
| 	//template <class Rep, class Period>
 |     //template <class Rep, class Period>
 | ||||||
| 	//cv_status wait_for(unique_lock<mutex>& lock,
 |     //cv_status wait_for(unique_lock<mutex>& lock,
 | ||||||
| 	//	const chrono::duration<Rep, Period>& rel_time);
 |     //    const chrono::duration<Rep, Period>& rel_time);
 | ||||||
| 
 | 
 | ||||||
| 	//template <class Rep, class Period, class Predicate>
 |     //template <class Rep, class Period, class Predicate>
 | ||||||
| 	//	bool wait_for(unique_lock<mutex>& lock,
 |     //    bool wait_for(unique_lock<mutex>& lock,
 | ||||||
| 	//	const chrono::duration<Rep, Period>& rel_time,
 |     //    const chrono::duration<Rep, Period>& rel_time,
 | ||||||
| 	//	Predicate pred);
 |     //    Predicate pred);
 | ||||||
| 
 | 
 | ||||||
| 	native_handle_type native_handle() |     native_handle_type native_handle() | ||||||
| 	{ |     { | ||||||
| #ifdef USE_EVENTS | #ifdef USE_EVENTS | ||||||
| 		return m_handle; |         return m_handle; | ||||||
| #else | #else | ||||||
| 		return &m_handle; |         return &m_handle; | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	native_type m_handle; |     native_type m_handle; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| #ifndef MUTEX_H_ | #ifndef MUTEX_H_ | ||||||
| #define 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__) | #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) | ||||||
| 
 | 
 | ||||||
| #ifndef __has_include | #ifndef __has_include | ||||||
|  | @ -46,72 +46,72 @@ namespace std | ||||||
| class recursive_mutex | class recursive_mutex | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	typedef CRITICAL_SECTION native_type; |     typedef CRITICAL_SECTION native_type; | ||||||
| #else | #else | ||||||
| 	typedef pthread_mutex_t native_type; |     typedef pthread_mutex_t native_type; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
| 	typedef native_type* native_handle_type; |     typedef native_type* native_handle_type; | ||||||
| 
 | 
 | ||||||
| 	recursive_mutex(const recursive_mutex&) /*= delete*/; |     recursive_mutex(const recursive_mutex&) /*= delete*/; | ||||||
| 	recursive_mutex& operator=(const recursive_mutex&) /*= delete*/; |     recursive_mutex& operator=(const recursive_mutex&) /*= delete*/; | ||||||
| 
 | 
 | ||||||
| 	recursive_mutex() |     recursive_mutex() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		InitializeCriticalSection(&m_handle); |         InitializeCriticalSection(&m_handle); | ||||||
| #else | #else | ||||||
| 		pthread_mutexattr_t attr; |         pthread_mutexattr_t attr; | ||||||
| 		pthread_mutexattr_init(&attr); |         pthread_mutexattr_init(&attr); | ||||||
| 		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); |         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | ||||||
| 		pthread_mutex_init(&m_handle, &attr); |         pthread_mutex_init(&m_handle, &attr); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	~recursive_mutex() |     ~recursive_mutex() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		DeleteCriticalSection(&m_handle); |         DeleteCriticalSection(&m_handle); | ||||||
| #else | #else | ||||||
| 		pthread_mutex_destroy(&m_handle); |         pthread_mutex_destroy(&m_handle); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void lock() |     void lock() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		EnterCriticalSection(&m_handle); |         EnterCriticalSection(&m_handle); | ||||||
| #else | #else | ||||||
| 		pthread_mutex_lock(&m_handle); |         pthread_mutex_lock(&m_handle); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void unlock() |     void unlock() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		LeaveCriticalSection(&m_handle); |         LeaveCriticalSection(&m_handle); | ||||||
| #else | #else | ||||||
| 		pthread_mutex_unlock(&m_handle); |         pthread_mutex_unlock(&m_handle); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	bool try_lock() |     bool try_lock() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		return (0 != TryEnterCriticalSection(&m_handle)); |         return (0 != TryEnterCriticalSection(&m_handle)); | ||||||
| #else | #else | ||||||
| 		return !pthread_mutex_trylock(&m_handle); |         return !pthread_mutex_trylock(&m_handle); | ||||||
| #endif     | #endif     | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	native_handle_type native_handle() |     native_handle_type native_handle() | ||||||
| 	{ |     { | ||||||
| 		return &m_handle; |         return &m_handle; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	native_type m_handle; |     native_type m_handle; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #if !defined(_WIN32) || defined(USE_SRWLOCKS) | #if !defined(_WIN32) || defined(USE_SRWLOCKS) | ||||||
|  | @ -119,74 +119,74 @@ private: | ||||||
| class mutex | class mutex | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	typedef SRWLOCK native_type; |     typedef SRWLOCK native_type; | ||||||
| #else | #else | ||||||
| 	typedef pthread_mutex_t native_type; |     typedef pthread_mutex_t native_type; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
| 	typedef native_type* native_handle_type; |     typedef native_type* native_handle_type; | ||||||
| 
 | 
 | ||||||
| 	mutex(const mutex&) /*= delete*/; |     mutex(const mutex&) /*= delete*/; | ||||||
| 	mutex& operator=(const mutex&) /*= delete*/; |     mutex& operator=(const mutex&) /*= delete*/; | ||||||
| 
 | 
 | ||||||
| 	mutex() |     mutex() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		InitializeSRWLock(&m_handle); |         InitializeSRWLock(&m_handle); | ||||||
| #else | #else | ||||||
| 		pthread_mutex_init(&m_handle, NULL); |         pthread_mutex_init(&m_handle, NULL); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	~mutex() |     ~mutex() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| #else | #else | ||||||
| 		pthread_mutex_destroy(&m_handle); |         pthread_mutex_destroy(&m_handle); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void lock() |     void lock() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		AcquireSRWLockExclusive(&m_handle); |         AcquireSRWLockExclusive(&m_handle); | ||||||
| #else | #else | ||||||
| 		pthread_mutex_lock(&m_handle); |         pthread_mutex_lock(&m_handle); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void unlock() |     void unlock() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		ReleaseSRWLockExclusive(&m_handle); |         ReleaseSRWLockExclusive(&m_handle); | ||||||
| #else | #else | ||||||
| 		pthread_mutex_unlock(&m_handle); |         pthread_mutex_unlock(&m_handle); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	bool try_lock() |     bool try_lock() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		// XXX TryAcquireSRWLockExclusive requires Windows 7!
 |         // XXX TryAcquireSRWLockExclusive requires Windows 7!
 | ||||||
| 		// return (0 != TryAcquireSRWLockExclusive(&m_handle));
 |         // return (0 != TryAcquireSRWLockExclusive(&m_handle));
 | ||||||
| 		return false; |         return false; | ||||||
| #else | #else | ||||||
| 		return !pthread_mutex_trylock(&m_handle); |         return !pthread_mutex_trylock(&m_handle); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	native_handle_type native_handle() |     native_handle_type native_handle() | ||||||
| 	{ |     { | ||||||
| 		return &m_handle; |         return &m_handle; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	native_type m_handle; |     native_type m_handle; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #else | #else | ||||||
| typedef recursive_mutex mutex;	// just use CriticalSections
 | typedef recursive_mutex mutex;    // just use CriticalSections
 | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | @ -198,165 +198,165 @@ template <class Mutex> | ||||||
| class lock_guard | class lock_guard | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	typedef Mutex mutex_type; |     typedef Mutex mutex_type; | ||||||
| 
 | 
 | ||||||
| 	explicit lock_guard(mutex_type& m) |     explicit lock_guard(mutex_type& m) | ||||||
| 		: pm(m) |         : pm(m) | ||||||
| 	{ |     { | ||||||
| 		m.lock(); |         m.lock(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	lock_guard(mutex_type& m, adopt_lock_t) |     lock_guard(mutex_type& m, adopt_lock_t) | ||||||
| 		: pm(m) |         : pm(m) | ||||||
| 	{ |     { | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	~lock_guard() |     ~lock_guard() | ||||||
| 	{ |     { | ||||||
| 		pm.unlock(); |         pm.unlock(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	lock_guard(lock_guard const&) /*= delete*/; |     lock_guard(lock_guard const&) /*= delete*/; | ||||||
| 	lock_guard& operator=(lock_guard const&) /*= delete*/; |     lock_guard& operator=(lock_guard const&) /*= delete*/; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	mutex_type& pm; |     mutex_type& pm; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template <class Mutex> | template <class Mutex> | ||||||
| class unique_lock | class unique_lock | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	typedef Mutex mutex_type; |     typedef Mutex mutex_type; | ||||||
| 
 | 
 | ||||||
| 	unique_lock() |     unique_lock() | ||||||
| 		: pm(NULL), owns(false) |         : pm(NULL), owns(false) | ||||||
| 	{} |     {} | ||||||
| 
 | 
 | ||||||
| 	/*explicit*/ unique_lock(mutex_type& m) |     /*explicit*/ unique_lock(mutex_type& m) | ||||||
| 		: pm(&m), owns(true) |         : pm(&m), owns(true) | ||||||
| 	{ |     { | ||||||
| 		m.lock(); |         m.lock(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	unique_lock(mutex_type& m, defer_lock_t) |     unique_lock(mutex_type& m, defer_lock_t) | ||||||
| 		: pm(&m), owns(false) |         : pm(&m), owns(false) | ||||||
| 	{} |     {} | ||||||
| 
 | 
 | ||||||
| 	unique_lock(mutex_type& m, try_to_lock_t) |     unique_lock(mutex_type& m, try_to_lock_t) | ||||||
| 		: pm(&m), owns(m.try_lock()) |         : pm(&m), owns(m.try_lock()) | ||||||
| 	{} |     {} | ||||||
| 
 | 
 | ||||||
| 	unique_lock(mutex_type& m, adopt_lock_t) |     unique_lock(mutex_type& m, adopt_lock_t) | ||||||
| 		: pm(&m), owns(true) |         : pm(&m), owns(true) | ||||||
| 	{} |     {} | ||||||
| 
 | 
 | ||||||
| 	//template <class Clock, class Duration>
 |     //template <class Clock, class Duration>
 | ||||||
| 	//unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
 |     //unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
 | ||||||
| 
 | 
 | ||||||
| 	//template <class Rep, class Period>
 |     //template <class Rep, class Period>
 | ||||||
| 	//unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
 |     //unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
 | ||||||
| 
 | 
 | ||||||
| 	~unique_lock() |     ~unique_lock() | ||||||
| 	{ |     { | ||||||
| 		if (owns_lock()) |         if (owns_lock()) | ||||||
| 			mutex()->unlock(); |             mutex()->unlock(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| #ifdef USE_RVALUE_REFERENCES | #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 | #else | ||||||
| 	unique_lock& operator=(const unique_lock& u) |     unique_lock& operator=(const unique_lock& u) | ||||||
| 	{ |     { | ||||||
| 		// ugly const_cast to get around lack of rvalue references
 |         // ugly const_cast to get around lack of rvalue references
 | ||||||
| 		unique_lock& other = const_cast<unique_lock&>(u); |         unique_lock& other = const_cast<unique_lock&>(u); | ||||||
| #endif | #endif | ||||||
| 		swap(other); |         swap(other); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
|      |      | ||||||
| #ifdef USE_RVALUE_REFERENCES | #ifdef USE_RVALUE_REFERENCES | ||||||
| 	unique_lock(const unique_lock&) /*= delete*/; |     unique_lock(const unique_lock&) /*= delete*/; | ||||||
|      |      | ||||||
| 	unique_lock(unique_lock&& other) |     unique_lock(unique_lock&& other) | ||||||
| 		: pm(NULL), owns(false) |         : pm(NULL), owns(false) | ||||||
| 	{ |     { | ||||||
| #else | #else | ||||||
| 	unique_lock(const unique_lock& u) |     unique_lock(const unique_lock& u) | ||||||
| 		: pm(NULL), owns(false) |         : pm(NULL), owns(false) | ||||||
| 	{ |     { | ||||||
| 		// ugly const_cast to get around lack of rvalue references
 |         // ugly const_cast to get around lack of rvalue references
 | ||||||
| 		unique_lock& other = const_cast<unique_lock&>(u);	 |         unique_lock& other = const_cast<unique_lock&>(u);     | ||||||
| #endif | #endif | ||||||
| 		swap(other); |         swap(other); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void lock() |     void lock() | ||||||
| 	{ |     { | ||||||
| 		mutex()->lock(); |         mutex()->lock(); | ||||||
| 		owns = true; |         owns = true; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	bool try_lock() |     bool try_lock() | ||||||
| 	{ |     { | ||||||
| 		owns = mutex()->try_lock(); |         owns = mutex()->try_lock(); | ||||||
| 		return owns; |         return owns; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	//template <class Rep, class Period>
 |     //template <class Rep, class Period>
 | ||||||
| 	//bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
 |     //bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
 | ||||||
| 	//template <class Clock, class Duration>
 |     //template <class Clock, class Duration>
 | ||||||
| 	//bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
 |     //bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
 | ||||||
|      |      | ||||||
| 	void unlock() |     void unlock() | ||||||
| 	{ |     { | ||||||
| 		mutex()->unlock(); |         mutex()->unlock(); | ||||||
| 		owns = false; |         owns = false; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void swap(unique_lock& u) |     void swap(unique_lock& u) | ||||||
| 	{ |     { | ||||||
| 		std::swap(pm, u.pm); |         std::swap(pm, u.pm); | ||||||
| 		std::swap(owns, u.owns); |         std::swap(owns, u.owns); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	mutex_type* release() |     mutex_type* release() | ||||||
| 	{ |     { | ||||||
| 		auto const ret = mutex(); |         auto const ret = mutex(); | ||||||
| 
 | 
 | ||||||
| 		pm = NULL; |         pm = NULL; | ||||||
| 		owns = false; |         owns = false; | ||||||
| 
 | 
 | ||||||
| 		return ret; |         return ret; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	bool owns_lock() const |     bool owns_lock() const | ||||||
| 	{ |     { | ||||||
| 		return owns; |         return owns; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	//explicit operator bool () const
 |     //explicit operator bool () const
 | ||||||
| 	//{
 |     //{
 | ||||||
| 	//	return owns_lock();
 |     //    return owns_lock();
 | ||||||
| 	//}
 |     //}
 | ||||||
| 
 | 
 | ||||||
| 	mutex_type* mutex() const |     mutex_type* mutex() const | ||||||
| 	{ |     { | ||||||
| 		return pm; |         return pm; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	mutex_type* pm; |     mutex_type* pm; | ||||||
| 	bool owns; |     bool owns; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template <class Mutex> | template <class Mutex> | ||||||
| void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) | void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) | ||||||
| { | { | ||||||
| 	x.swap(y); |     x.swap(y); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| #ifndef STD_THREAD_H_ | #ifndef STD_THREAD_H_ | ||||||
| #define 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__) | #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) | ||||||
| 
 | 
 | ||||||
| #ifndef __has_include | #ifndef __has_include | ||||||
|  | @ -77,209 +77,209 @@ namespace std | ||||||
| class thread | class thread | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	typedef THREAD_HANDLE native_handle_type; |     typedef THREAD_HANDLE native_handle_type; | ||||||
| 
 | 
 | ||||||
| 	class id |     class id | ||||||
| 	{ |     { | ||||||
| 		friend class thread; |         friend class thread; | ||||||
| 	public: |     public: | ||||||
| 		id() : m_thread(0) {} |         id() : m_thread(0) {} | ||||||
| 		id(THREAD_ID _id) : m_thread(_id) {} |         id(THREAD_ID _id) : m_thread(_id) {} | ||||||
| 
 | 
 | ||||||
| 		bool operator==(const id& rhs) const |         bool operator==(const id& rhs) const | ||||||
| 		{ |         { | ||||||
| 			return m_thread == rhs.m_thread; |             return m_thread == rhs.m_thread; | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		bool operator!=(const id& rhs) const |         bool operator!=(const id& rhs) const | ||||||
| 		{ |         { | ||||||
| 			return !(*this == rhs); |             return !(*this == rhs); | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		bool operator<(const id& rhs) const |         bool operator<(const id& rhs) const | ||||||
| 		{ |         { | ||||||
| 			return m_thread < rhs.m_thread; |             return m_thread < rhs.m_thread; | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 	private: |     private: | ||||||
| 		THREAD_ID m_thread; |         THREAD_ID m_thread; | ||||||
| 	}; |     }; | ||||||
| 
 | 
 | ||||||
| 	// no variadic template support in msvc
 |     // no variadic template support in msvc
 | ||||||
| 	//template <typename C, typename... A>
 |     //template <typename C, typename... A>
 | ||||||
| 	//thread(C&& func, A&&... args);
 |     //thread(C&& func, A&&... args);
 | ||||||
| 
 | 
 | ||||||
| 	template <typename C> |     template <typename C> | ||||||
| 	thread(C func) |     thread(C func) | ||||||
| 	{ |     { | ||||||
| 		StartThread(new Func<C>(func)); |         StartThread(new Func<C>(func)); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	template <typename C, typename A> |     template <typename C, typename A> | ||||||
| 	thread(C func, A arg) |     thread(C func, A arg) | ||||||
| 	{ |     { | ||||||
| 		StartThread(new FuncArg<C, A>(func, arg)); |         StartThread(new FuncArg<C, A>(func, arg)); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	thread() /*= default;*/ {} |     thread() /*= default;*/ {} | ||||||
| 
 | 
 | ||||||
| #ifdef USE_RVALUE_REFERENCES | #ifdef USE_RVALUE_REFERENCES | ||||||
| 	thread(const thread&) /*= delete*/; |     thread(const thread&) /*= delete*/; | ||||||
| 
 | 
 | ||||||
| 	thread(thread&& other) |     thread(thread&& other) | ||||||
| 	{ |     { | ||||||
| #else | #else | ||||||
| 	thread(const thread& t) |     thread(const thread& t) | ||||||
| 	{ |     { | ||||||
| 		// ugly const_cast to get around lack of rvalue references
 |         // ugly const_cast to get around lack of rvalue references
 | ||||||
| 		thread& other = const_cast<thread&>(t); |         thread& other = const_cast<thread&>(t); | ||||||
| #endif | #endif | ||||||
| 		swap(other); |         swap(other); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| #ifdef USE_RVALUE_REFERENCES | #ifdef USE_RVALUE_REFERENCES | ||||||
| 	thread& operator=(const thread&) /*= delete*/; |     thread& operator=(const thread&) /*= delete*/; | ||||||
| 
 | 
 | ||||||
| 	thread& operator=(thread&& other) |     thread& operator=(thread&& other) | ||||||
| 	{ |     { | ||||||
| #else | #else | ||||||
| 	thread& operator=(const thread& t) |     thread& operator=(const thread& t) | ||||||
| 	{ |     { | ||||||
| 		// ugly const_cast to get around lack of rvalue references
 |         // ugly const_cast to get around lack of rvalue references
 | ||||||
| 		thread& other = const_cast<thread&>(t); |         thread& other = const_cast<thread&>(t); | ||||||
| #endif | #endif | ||||||
| 		if (joinable()) |         if (joinable()) | ||||||
| 			detach(); |             detach(); | ||||||
| 		swap(other); |         swap(other); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	~thread() |     ~thread() | ||||||
| 	{ |     { | ||||||
| 		if (joinable()) |         if (joinable()) | ||||||
| 			detach(); |             detach(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	bool joinable() const |     bool joinable() const | ||||||
| 	{ |     { | ||||||
| 		return m_id != id(); |         return m_id != id(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	id get_id() const |     id get_id() const | ||||||
| 	{ |     { | ||||||
| 		return m_id; |         return m_id; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	native_handle_type native_handle() |     native_handle_type native_handle() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		return m_handle; |         return m_handle; | ||||||
| #else | #else | ||||||
| 		return m_id.m_thread; |         return m_id.m_thread; | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void join() |     void join() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		WaitForSingleObject(m_handle, INFINITE); |         WaitForSingleObject(m_handle, INFINITE); | ||||||
| 		detach(); |         detach(); | ||||||
| #else | #else | ||||||
| 		pthread_join(m_id.m_thread, NULL); |         pthread_join(m_id.m_thread, NULL); | ||||||
| 		m_id = id(); |         m_id = id(); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void detach() |     void detach() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		CloseHandle(m_handle); |         CloseHandle(m_handle); | ||||||
| #else | #else | ||||||
| 		pthread_detach(m_id.m_thread); |         pthread_detach(m_id.m_thread); | ||||||
| #endif | #endif | ||||||
| 		m_id = id(); |         m_id = id(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void swap(thread& other) |     void swap(thread& other) | ||||||
| 	{ |     { | ||||||
| 		std::swap(m_id, other.m_id); |         std::swap(m_id, other.m_id); | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		std::swap(m_handle, other.m_handle); |         std::swap(m_handle, other.m_handle); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
|      |      | ||||||
| 	static unsigned hardware_concurrency() |     static unsigned hardware_concurrency() | ||||||
| 	{ |     { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		SYSTEM_INFO sysinfo; |         SYSTEM_INFO sysinfo; | ||||||
| 		GetSystemInfo(&sysinfo); |         GetSystemInfo(&sysinfo); | ||||||
| 		return static_cast<unsigned>(sysinfo.dwNumberOfProcessors); |         return static_cast<unsigned>(sysinfo.dwNumberOfProcessors); | ||||||
| #else | #else | ||||||
| 		return 0; |         return 0; | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	id m_id; |     id m_id; | ||||||
|      |      | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	native_handle_type m_handle; |     native_handle_type m_handle; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	template <typename F> |     template <typename F> | ||||||
| 	void StartThread(F* param) |     void StartThread(F* param) | ||||||
| 	{ |     { | ||||||
| #ifdef USE_BEGINTHREADEX | #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) | #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 | #else | ||||||
| 		pthread_attr_t attr; |         pthread_attr_t attr; | ||||||
| 		pthread_attr_init(&attr); |         pthread_attr_init(&attr); | ||||||
| 		pthread_attr_setstacksize(&attr, 1024 * 1024); |         pthread_attr_setstacksize(&attr, 1024 * 1024); | ||||||
| 		if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param)) |         if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param)) | ||||||
| 			m_id = id(); |             m_id = id(); | ||||||
| #endif | #endif | ||||||
| 	} |     } | ||||||
|      |      | ||||||
| 	template <typename C> |     template <typename C> | ||||||
| 	class Func |     class Func | ||||||
| 	{ |     { | ||||||
| 	public: |     public: | ||||||
| 		Func(C _func) : func(_func) {} |         Func(C _func) : func(_func) {} | ||||||
| 
 | 
 | ||||||
| 		void Run() { func(); } |         void Run() { func(); } | ||||||
| 
 | 
 | ||||||
| 	private: |     private: | ||||||
| 		C const func; |         C const func; | ||||||
| 	}; |     }; | ||||||
| 
 | 
 | ||||||
| 	template <typename C, typename A> |     template <typename C, typename A> | ||||||
| 	class FuncArg |     class FuncArg | ||||||
| 	{ |     { | ||||||
| 	public: |     public: | ||||||
| 		FuncArg(C _func, A _arg) : func(_func), arg(_arg) {} |         FuncArg(C _func, A _arg) : func(_func), arg(_arg) {} | ||||||
| 
 | 
 | ||||||
| 		void Run() { func(arg); } |         void Run() { func(arg); } | ||||||
| 
 | 
 | ||||||
| 	private: |     private: | ||||||
| 		C const func; |         C const func; | ||||||
| 		A arg; |         A arg; | ||||||
| 	}; |     }; | ||||||
| 
 | 
 | ||||||
| 	template <typename F> |     template <typename F> | ||||||
| 	static THREAD_RETURN RunAndDelete(void* param) |     static THREAD_RETURN RunAndDelete(void* param) | ||||||
| 	{ |     { | ||||||
| #ifdef __APPLE__ | #ifdef __APPLE__ | ||||||
| 		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||||
| #endif | #endif | ||||||
| 		static_cast<F*>(param)->Run(); |         static_cast<F*>(param)->Run(); | ||||||
| 		delete static_cast<F*>(param); |         delete static_cast<F*>(param); | ||||||
| #ifdef __APPLE__ | #ifdef __APPLE__ | ||||||
| 		[pool release]; |         [pool release]; | ||||||
| #endif | #endif | ||||||
| 		return 0; |         return 0; | ||||||
| 	} |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| namespace this_thread | namespace this_thread | ||||||
|  | @ -288,24 +288,24 @@ namespace this_thread | ||||||
| inline void yield() | inline void yield() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	SwitchToThread(); |     SwitchToThread(); | ||||||
| #else | #else | ||||||
| 	sleep(0); |     sleep(0); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline thread::id get_id() | inline thread::id get_id() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	return GetCurrentThreadId(); |     return GetCurrentThreadId(); | ||||||
| #else | #else | ||||||
| 	return pthread_self(); |     return pthread_self(); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| }	// namespace this_thread
 | }    // namespace this_thread
 | ||||||
| 
 | 
 | ||||||
| }	// namespace std
 | }    // namespace std
 | ||||||
| 
 | 
 | ||||||
| #undef USE_RVALUE_REFERENCES | #undef USE_RVALUE_REFERENCES | ||||||
| #undef USE_BEGINTHREADEX | #undef USE_BEGINTHREADEX | ||||||
|  |  | ||||||
|  | @ -11,131 +11,131 @@ | ||||||
| #include "string_util.h" | #include "string_util.h" | ||||||
| 
 | 
 | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	#include <Windows.h> |     #include <Windows.h> | ||||||
| #else | #else | ||||||
| 	#include <iconv.h> |     #include <iconv.h> | ||||||
| 	#include <errno.h> |     #include <errno.h> | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| // faster than sscanf
 | // faster than sscanf
 | ||||||
| bool AsciiToHex(const char* _szValue, u32& result) | bool AsciiToHex(const char* _szValue, u32& result) | ||||||
| { | { | ||||||
| 	char *endptr = NULL; |     char *endptr = NULL; | ||||||
| 	const u32 value = strtoul(_szValue, &endptr, 16); |     const u32 value = strtoul(_szValue, &endptr, 16); | ||||||
| 
 | 
 | ||||||
| 	if (!endptr || *endptr) |     if (!endptr || *endptr) | ||||||
| 		return false; |         return false; | ||||||
| 
 | 
 | ||||||
| 	result = value; |     result = value; | ||||||
| 	return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) | bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) | ||||||
| { | { | ||||||
| 	int writtenCount; |     int writtenCount; | ||||||
| 
 | 
 | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	// You would think *printf are simple, right? Iterate on each character,
 |     // You would think *printf are simple, right? Iterate on each character,
 | ||||||
| 	// if it's a format specifier handle it properly, etc.
 |     // if it's a format specifier handle it properly, etc.
 | ||||||
| 	//
 |     //
 | ||||||
| 	// Nooooo. Not according to the C standard.
 |     // Nooooo. Not according to the C standard.
 | ||||||
| 	//
 |     //
 | ||||||
| 	// According to the C99 standard (7.19.6.1 "The fprintf function")
 |     // According to the C99 standard (7.19.6.1 "The fprintf function")
 | ||||||
| 	//     The format shall be a multibyte character sequence
 |     //     The format shall be a multibyte character sequence
 | ||||||
| 	//
 |     //
 | ||||||
| 	// Because some character encodings might have '%' signs in the middle of
 |     // Because some character encodings might have '%' signs in the middle of
 | ||||||
| 	// a multibyte sequence (SJIS for example only specifies that the first
 |     // 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),
 |     // 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
 |     // printf functions have to decode the multibyte sequences and try their
 | ||||||
| 	// best to not screw up.
 |     // best to not screw up.
 | ||||||
| 	//
 |     //
 | ||||||
| 	// Unfortunately, on Windows, the locale for most languages is not UTF-8
 |     // 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
 |     // 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.
 |     // 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
 |     // 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
 |     // multibyte handling is required as we can simply assume that no '%' char
 | ||||||
| 	// will be present in the middle of a multibyte sequence.
 |     // will be present in the middle of a multibyte sequence.
 | ||||||
| 	//
 |     //
 | ||||||
| 	// This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l.
 |     // This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l.
 | ||||||
| 	static locale_t c_locale = NULL; |     static locale_t c_locale = NULL; | ||||||
| 	if (!c_locale) |     if (!c_locale) | ||||||
| 		c_locale = _create_locale(LC_ALL, ".1252"); |         c_locale = _create_locale(LC_ALL, ".1252"); | ||||||
| 	writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); |     writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); | ||||||
| #else | #else | ||||||
| 	writtenCount = vsnprintf(out, outsize, format, args); |     writtenCount = vsnprintf(out, outsize, format, args); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	if (writtenCount > 0 && writtenCount < outsize) |     if (writtenCount > 0 && writtenCount < outsize) | ||||||
| 	{ |     { | ||||||
| 		out[writtenCount] = '\0'; |         out[writtenCount] = '\0'; | ||||||
| 		return true; |         return true; | ||||||
| 	} |     } | ||||||
| 	else |     else | ||||||
| 	{ |     { | ||||||
| 		out[outsize - 1] = '\0'; |         out[outsize - 1] = '\0'; | ||||||
| 		return false; |         return false; | ||||||
| 	} |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string StringFromFormat(const char* format, ...) | std::string StringFromFormat(const char* format, ...) | ||||||
| { | { | ||||||
| 	va_list args; |     va_list args; | ||||||
| 	char *buf = NULL; |     char *buf = NULL; | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	int required = 0; |     int required = 0; | ||||||
| 
 | 
 | ||||||
| 	va_start(args, format); |     va_start(args, format); | ||||||
| 	required = _vscprintf(format, args); |     required = _vscprintf(format, args); | ||||||
| 	buf = new char[required + 1]; |     buf = new char[required + 1]; | ||||||
| 	CharArrayFromFormatV(buf, required + 1, format, args); |     CharArrayFromFormatV(buf, required + 1, format, args); | ||||||
| 	va_end(args); |     va_end(args); | ||||||
| 
 | 
 | ||||||
| 	std::string temp = buf; |     std::string temp = buf; | ||||||
| 	delete[] buf; |     delete[] buf; | ||||||
| #else | #else | ||||||
| 	va_start(args, format); |     va_start(args, format); | ||||||
| 	if (vasprintf(&buf, format, args) < 0) |     if (vasprintf(&buf, format, args) < 0) | ||||||
| 		ERROR_LOG(COMMON, "Unable to allocate memory for string"); |         ERROR_LOG(COMMON, "Unable to allocate memory for string"); | ||||||
| 	va_end(args); |     va_end(args); | ||||||
| 
 | 
 | ||||||
| 	std::string temp = buf; |     std::string temp = buf; | ||||||
| 	free(buf); |     free(buf); | ||||||
| #endif | #endif | ||||||
| 	return temp; |     return temp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // For Debugging. Read out an u8 array.
 | // For Debugging. Read out an u8 array.
 | ||||||
| std::string ArrayToString(const u8 *data, u32 size, int line_len, bool spaces) | std::string ArrayToString(const u8 *data, u32 size, int line_len, bool spaces) | ||||||
| { | { | ||||||
| 	std::ostringstream oss; |     std::ostringstream oss; | ||||||
| 	oss << std::setfill('0') << std::hex; |     oss << std::setfill('0') << std::hex; | ||||||
|      |      | ||||||
| 	for (int line = 0; size; ++data, --size) |     for (int line = 0; size; ++data, --size) | ||||||
| 	{ |     { | ||||||
| 		oss << std::setw(2) << (int)*data; |         oss << std::setw(2) << (int)*data; | ||||||
|          |          | ||||||
| 		if (line_len == ++line) |         if (line_len == ++line) | ||||||
| 		{ |         { | ||||||
| 			oss << '\n'; |             oss << '\n'; | ||||||
| 			line = 0; |             line = 0; | ||||||
| 		} |         } | ||||||
| 		else if (spaces) |         else if (spaces) | ||||||
| 			oss << ' '; |             oss << ' '; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	return oss.str(); |     return oss.str(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Turns "  hej " into "hej". Also handles tabs.
 | // Turns "  hej " into "hej". Also handles tabs.
 | ||||||
| std::string StripSpaces(const std::string &str) | 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) |     if (str.npos != s) | ||||||
| 		return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); |         return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); | ||||||
| 	else |     else | ||||||
| 		return ""; |         return ""; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // "\"hello\"" is turned to "hello"
 | // "\"hello\"" is turned to "hello"
 | ||||||
|  | @ -143,137 +143,137 @@ std::string StripSpaces(const std::string &str) | ||||||
| // ends, as done by StripSpaces above, for example.
 | // ends, as done by StripSpaces above, for example.
 | ||||||
| std::string StripQuotes(const std::string& s) | std::string StripQuotes(const std::string& s) | ||||||
| { | { | ||||||
| 	if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) |     if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) | ||||||
| 		return s.substr(1, s.size() - 2); |         return s.substr(1, s.size() - 2); | ||||||
| 	else |     else | ||||||
| 		return s; |         return s; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool TryParse(const std::string &str, u32 *const output) | bool TryParse(const std::string &str, u32 *const output) | ||||||
| { | { | ||||||
| 	char *endptr = NULL; |     char *endptr = NULL; | ||||||
| 
 | 
 | ||||||
| 	// Reset errno to a value other than ERANGE
 |     // Reset errno to a value other than ERANGE
 | ||||||
| 	errno = 0; |     errno = 0; | ||||||
| 
 | 
 | ||||||
| 	unsigned long value = strtoul(str.c_str(), &endptr, 0); |     unsigned long value = strtoul(str.c_str(), &endptr, 0); | ||||||
|      |      | ||||||
| 	if (!endptr || *endptr) |     if (!endptr || *endptr) | ||||||
| 		return false; |         return false; | ||||||
| 
 | 
 | ||||||
| 	if (errno == ERANGE) |     if (errno == ERANGE) | ||||||
| 		return false; |         return false; | ||||||
| 
 | 
 | ||||||
| #if ULONG_MAX > UINT_MAX | #if ULONG_MAX > UINT_MAX | ||||||
| 	if (value >= 0x100000000ull |     if (value >= 0x100000000ull | ||||||
| 	    && value <= 0xFFFFFFFF00000000ull) |         && value <= 0xFFFFFFFF00000000ull) | ||||||
| 		return false; |         return false; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	*output = static_cast<u32>(value); |     *output = static_cast<u32>(value); | ||||||
| 	return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool TryParse(const std::string &str, bool *const output) | bool TryParse(const std::string &str, bool *const output) | ||||||
| { | { | ||||||
| 	if ("1" == str || !strcasecmp("true", str.c_str())) |     if ("1" == str || !strcasecmp("true", str.c_str())) | ||||||
| 		*output = true; |         *output = true; | ||||||
| 	else if ("0" == str || !strcasecmp("false", str.c_str())) |     else if ("0" == str || !strcasecmp("false", str.c_str())) | ||||||
| 		*output = false; |         *output = false; | ||||||
| 	else |     else | ||||||
| 		return false; |         return false; | ||||||
| 
 | 
 | ||||||
| 	return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string StringFromInt(int value) | std::string StringFromInt(int value) | ||||||
| { | { | ||||||
| 	char temp[16]; |     char temp[16]; | ||||||
| 	sprintf(temp, "%i", value); |     sprintf(temp, "%i", value); | ||||||
| 	return temp; |     return temp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string StringFromBool(bool value) | 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) | bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension) | ||||||
| { | { | ||||||
| 	if (full_path.empty()) |     if (full_path.empty()) | ||||||
| 		return false; |         return false; | ||||||
| 
 | 
 | ||||||
| 	size_t dir_end = full_path.find_last_of("/" |     size_t dir_end = full_path.find_last_of("/" | ||||||
| 	// windows needs the : included for something like just "C:" to be considered a directory
 |     // windows needs the : included for something like just "C:" to be considered a directory
 | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		":" |         ":" | ||||||
| #endif | #endif | ||||||
| 	); |     ); | ||||||
| 	if (std::string::npos == dir_end) |     if (std::string::npos == dir_end) | ||||||
| 		dir_end = 0; |         dir_end = 0; | ||||||
| 	else |     else | ||||||
| 		dir_end += 1; |         dir_end += 1; | ||||||
| 
 | 
 | ||||||
| 	size_t fname_end = full_path.rfind('.'); |     size_t fname_end = full_path.rfind('.'); | ||||||
| 	if (fname_end < dir_end || std::string::npos == fname_end) |     if (fname_end < dir_end || std::string::npos == fname_end) | ||||||
| 		fname_end = full_path.size(); |         fname_end = full_path.size(); | ||||||
| 
 | 
 | ||||||
| 	if (_pPath) |     if (_pPath) | ||||||
| 		*_pPath = full_path.substr(0, dir_end); |         *_pPath = full_path.substr(0, dir_end); | ||||||
| 
 | 
 | ||||||
| 	if (_pFilename) |     if (_pFilename) | ||||||
| 		*_pFilename = full_path.substr(dir_end, fname_end - dir_end); |         *_pFilename = full_path.substr(dir_end, fname_end - dir_end); | ||||||
| 
 | 
 | ||||||
| 	if (_pExtension) |     if (_pExtension) | ||||||
| 		*_pExtension = full_path.substr(fname_end); |         *_pExtension = full_path.substr(fname_end); | ||||||
| 
 | 
 | ||||||
| 	return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, const std::string& _Filename) | void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, const std::string& _Filename) | ||||||
| { | { | ||||||
| 	_CompleteFilename = _Path; |     _CompleteFilename = _Path; | ||||||
| 
 | 
 | ||||||
| 	// check for seperator
 |     // check for seperator
 | ||||||
| 	if (DIR_SEP_CHR != *_CompleteFilename.rbegin()) |     if (DIR_SEP_CHR != *_CompleteFilename.rbegin()) | ||||||
| 		_CompleteFilename += DIR_SEP_CHR; |         _CompleteFilename += DIR_SEP_CHR; | ||||||
| 
 | 
 | ||||||
| 	// add the filename
 |     // add the filename
 | ||||||
| 	_CompleteFilename += _Filename; |     _CompleteFilename += _Filename; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SplitString(const std::string& str, const char delim, std::vector<std::string>& output) | void SplitString(const std::string& str, const char delim, std::vector<std::string>& output) | ||||||
| { | { | ||||||
| 	std::istringstream iss(str); |     std::istringstream iss(str); | ||||||
| 	output.resize(1); |     output.resize(1); | ||||||
| 
 | 
 | ||||||
| 	while (std::getline(iss, *output.rbegin(), delim)) |     while (std::getline(iss, *output.rbegin(), delim)) | ||||||
| 		output.push_back(""); |         output.push_back(""); | ||||||
| 
 | 
 | ||||||
| 	output.pop_back(); |     output.pop_back(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string TabsToSpaces(int tab_size, const std::string &in) | std::string TabsToSpaces(int tab_size, const std::string &in) | ||||||
| { | { | ||||||
| 	const std::string spaces(tab_size, ' '); |     const std::string spaces(tab_size, ' '); | ||||||
| 	std::string out(in); |     std::string out(in); | ||||||
| 
 | 
 | ||||||
| 	size_t i = 0; |     size_t i = 0; | ||||||
| 	while (out.npos != (i = out.find('\t'))) |     while (out.npos != (i = out.find('\t'))) | ||||||
| 		out.replace(i, 1, spaces); |         out.replace(i, 1, spaces); | ||||||
| 
 | 
 | ||||||
| 	return out; |     return out; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) | std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) | ||||||
| { | { | ||||||
| 	while(1) |     while(1) | ||||||
| 	{ |     { | ||||||
| 		size_t pos = result.find(src); |         size_t pos = result.find(src); | ||||||
| 		if (pos == std::string::npos) break; |         if (pos == std::string::npos) break; | ||||||
| 		result.replace(pos, src.size(), dest); |         result.replace(pos, src.size(), dest); | ||||||
| 	} |     } | ||||||
| 	return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // UriDecode and UriEncode are from http://www.codeguru.com/cpp/cpp/string/conversions/print.php/c12759
 | // 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] =  | const char HEX2DEC[256] =  | ||||||
| { | { | ||||||
| 	/*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */ |     /*       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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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 |     /* F */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| std::string UriDecode(const std::string & sSrc) | std::string UriDecode(const std::string & sSrc) | ||||||
| { | { | ||||||
| 	// Note from RFC1630:  "Sequences which start with a percent sign
 |     // Note from RFC1630:  "Sequences which start with a percent sign
 | ||||||
| 	// but are not followed by two hexadecimal characters (0-9, A-F) are reserved
 |     // but are not followed by two hexadecimal characters (0-9, A-F) are reserved
 | ||||||
| 	// for future extension"
 |     // for future extension"
 | ||||||
| 
 | 
 | ||||||
| 	const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); |     const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); | ||||||
| 	const size_t SRC_LEN = sSrc.length(); |     const size_t SRC_LEN = sSrc.length(); | ||||||
| 	const unsigned char * const SRC_END = pSrc + SRC_LEN; |     const unsigned char * const SRC_END = pSrc + SRC_LEN; | ||||||
| 	const unsigned char * const SRC_LAST_DEC = SRC_END - 2;   // last decodable '%' 
 |     const unsigned char * const SRC_LAST_DEC = SRC_END - 2;   // last decodable '%' 
 | ||||||
| 
 | 
 | ||||||
| 	char * const pStart = new char[SRC_LEN]; |     char * const pStart = new char[SRC_LEN]; | ||||||
| 	char * pEnd = pStart; |     char * pEnd = pStart; | ||||||
| 
 | 
 | ||||||
| 	while (pSrc < SRC_LAST_DEC) |     while (pSrc < SRC_LAST_DEC) | ||||||
| 	{ |     { | ||||||
| 		if (*pSrc == '%') |         if (*pSrc == '%') | ||||||
| 		{ |         { | ||||||
| 			char dec1, dec2; |             char dec1, dec2; | ||||||
| 			if (16 != (dec1 = HEX2DEC[*(pSrc + 1)]) |             if (16 != (dec1 = HEX2DEC[*(pSrc + 1)]) | ||||||
| 				&& 16 != (dec2 = HEX2DEC[*(pSrc + 2)])) |                 && 16 != (dec2 = HEX2DEC[*(pSrc + 2)])) | ||||||
| 			{ |             { | ||||||
| 				*pEnd++ = (dec1 << 4) + dec2; |                 *pEnd++ = (dec1 << 4) + dec2; | ||||||
| 				pSrc += 3; |                 pSrc += 3; | ||||||
| 				continue; |                 continue; | ||||||
| 			} |             } | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		*pEnd++ = *pSrc++; |         *pEnd++ = *pSrc++; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// the last 2- chars
 |     // the last 2- chars
 | ||||||
| 	while (pSrc < SRC_END) |     while (pSrc < SRC_END) | ||||||
| 		*pEnd++ = *pSrc++; |         *pEnd++ = *pSrc++; | ||||||
| 
 | 
 | ||||||
| 	std::string sResult(pStart, pEnd); |     std::string sResult(pStart, pEnd); | ||||||
| 	delete [] pStart; |     delete [] pStart; | ||||||
| 	return sResult; |     return sResult; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Only alphanum is safe.
 | // Only alphanum is safe.
 | ||||||
| const char SAFE[256] = | const char SAFE[256] = | ||||||
| { | { | ||||||
| 	/*      0 1 2 3  4 5 6 7  8 9 A B  C D E F */ |     /*      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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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, |     /* 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 |     /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| std::string UriEncode(const std::string & sSrc) | std::string UriEncode(const std::string & sSrc) | ||||||
| { | { | ||||||
| 	const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; |     const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; | ||||||
| 	const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); |     const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); | ||||||
| 	const size_t SRC_LEN = sSrc.length(); |     const size_t SRC_LEN = sSrc.length(); | ||||||
| 	unsigned char * const pStart = new unsigned char[SRC_LEN * 3]; |     unsigned char * const pStart = new unsigned char[SRC_LEN * 3]; | ||||||
| 	unsigned char * pEnd = pStart; |     unsigned char * pEnd = pStart; | ||||||
| 	const unsigned char * const SRC_END = pSrc + SRC_LEN; |     const unsigned char * const SRC_END = pSrc + SRC_LEN; | ||||||
| 
 | 
 | ||||||
| 	for (; pSrc < SRC_END; ++pSrc) |     for (; pSrc < SRC_END; ++pSrc) | ||||||
| 	{ |     { | ||||||
| 		if (SAFE[*pSrc])  |         if (SAFE[*pSrc])  | ||||||
| 			*pEnd++ = *pSrc; |             *pEnd++ = *pSrc; | ||||||
| 		else |         else | ||||||
| 		{ |         { | ||||||
| 			// escape this char
 |             // escape this char
 | ||||||
| 			*pEnd++ = '%'; |             *pEnd++ = '%'; | ||||||
| 			*pEnd++ = DEC2HEX[*pSrc >> 4]; |             *pEnd++ = DEC2HEX[*pSrc >> 4]; | ||||||
| 			*pEnd++ = DEC2HEX[*pSrc & 0x0F]; |             *pEnd++ = DEC2HEX[*pSrc & 0x0F]; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	std::string sResult((char *)pStart, (char *)pEnd); |     std::string sResult((char *)pStart, (char *)pEnd); | ||||||
| 	delete [] pStart; |     delete [] pStart; | ||||||
| 	return sResult; |     return sResult; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 
 | 
 | ||||||
| std::string UTF16ToUTF8(const std::wstring& input) | 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; |     std::string output; | ||||||
| 	output.resize(size); |     output.resize(size); | ||||||
| 
 | 
 | ||||||
| 	if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr)) |     if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr)) | ||||||
| 		output.clear(); |         output.clear(); | ||||||
| 
 | 
 | ||||||
| 	return output; |     return output; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::wstring CPToUTF16(u32 code_page, const std::string& input) | 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; |     std::wstring output; | ||||||
| 	output.resize(size); |     output.resize(size); | ||||||
| 
 | 
 | ||||||
| 	if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size())) |     if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size())) | ||||||
| 		output.clear(); |         output.clear(); | ||||||
| 
 | 
 | ||||||
| 	return output; |     return output; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::wstring UTF8ToUTF16(const std::string& input) | std::wstring UTF8ToUTF16(const std::string& input) | ||||||
| { | { | ||||||
| 	return CPToUTF16(CP_UTF8, input); |     return CPToUTF16(CP_UTF8, input); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string SHIFTJISToUTF8(const std::string& 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) | std::string CP1252ToUTF8(const std::string& input) | ||||||
| { | { | ||||||
| 	return UTF16ToUTF8(CPToUTF16(1252, input)); |     return UTF16ToUTF8(CPToUTF16(1252, input)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #else | #else | ||||||
|  | @ -449,83 +449,83 @@ std::string CP1252ToUTF8(const std::string& input) | ||||||
| template <typename T> | template <typename T> | ||||||
| std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& input) | 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); |     iconv_t const conv_desc = iconv_open("UTF-8", fromcode); | ||||||
| 	if ((iconv_t)-1 == conv_desc) |     if ((iconv_t)-1 == conv_desc) | ||||||
| 	{ |     { | ||||||
| 		ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno)); |         ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno)); | ||||||
| 	} |     } | ||||||
| 	else |     else | ||||||
| 	{ |     { | ||||||
| 		size_t const in_bytes = sizeof(T) * input.size(); |         size_t const in_bytes = sizeof(T) * input.size(); | ||||||
| 		size_t const out_buffer_size = 4 * in_bytes; |         size_t const out_buffer_size = 4 * in_bytes; | ||||||
| 
 | 
 | ||||||
| 		std::string out_buffer; |         std::string out_buffer; | ||||||
| 		out_buffer.resize(out_buffer_size); |         out_buffer.resize(out_buffer_size); | ||||||
| 
 | 
 | ||||||
| 		auto src_buffer = &input[0]; |         auto src_buffer = &input[0]; | ||||||
| 		size_t src_bytes = in_bytes; |         size_t src_bytes = in_bytes; | ||||||
| 		auto dst_buffer = &out_buffer[0]; |         auto dst_buffer = &out_buffer[0]; | ||||||
| 		size_t dst_bytes = out_buffer.size(); |         size_t dst_bytes = out_buffer.size(); | ||||||
| 
 | 
 | ||||||
| 		while (src_bytes != 0) |         while (src_bytes != 0) | ||||||
| 		{ |         { | ||||||
| 			size_t const iconv_result = iconv(conv_desc, (char**)(&src_buffer), &src_bytes, |             size_t const iconv_result = iconv(conv_desc, (char**)(&src_buffer), &src_bytes, | ||||||
| 				&dst_buffer, &dst_bytes); |                 &dst_buffer, &dst_bytes); | ||||||
| 
 | 
 | ||||||
| 			if ((size_t)-1 == iconv_result) |             if ((size_t)-1 == iconv_result) | ||||||
| 			{ |             { | ||||||
| 				if (EILSEQ == errno || EINVAL == errno) |                 if (EILSEQ == errno || EINVAL == errno) | ||||||
| 				{ |                 { | ||||||
| 					// Try to skip the bad character
 |                     // Try to skip the bad character
 | ||||||
| 					if (src_bytes != 0) |                     if (src_bytes != 0) | ||||||
| 					{ |                     { | ||||||
| 						--src_bytes; |                         --src_bytes; | ||||||
| 						++src_buffer; |                         ++src_buffer; | ||||||
| 					} |                     } | ||||||
| 				} |                 } | ||||||
| 				else |                 else | ||||||
| 				{ |                 { | ||||||
| 					ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno)); |                     ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno)); | ||||||
| 					break; |                     break; | ||||||
| 				} |                 } | ||||||
| 			} |             } | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 		out_buffer.resize(out_buffer_size - dst_bytes); |         out_buffer.resize(out_buffer_size - dst_bytes); | ||||||
| 		out_buffer.swap(result); |         out_buffer.swap(result); | ||||||
|          |          | ||||||
| 		iconv_close(conv_desc); |         iconv_close(conv_desc); | ||||||
| 	} |     } | ||||||
|      |      | ||||||
| 	return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string CP1252ToUTF8(const std::string& input) | std::string CP1252ToUTF8(const std::string& input) | ||||||
| { | { | ||||||
| 	//return CodeToUTF8("CP1252//TRANSLIT", input);
 |     //return CodeToUTF8("CP1252//TRANSLIT", input);
 | ||||||
| 	//return CodeToUTF8("CP1252//IGNORE", input);
 |     //return CodeToUTF8("CP1252//IGNORE", input);
 | ||||||
| 	return CodeToUTF8("CP1252", input); |     return CodeToUTF8("CP1252", input); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string SHIFTJISToUTF8(const std::string& input) | std::string SHIFTJISToUTF8(const std::string& input) | ||||||
| { | { | ||||||
| 	//return CodeToUTF8("CP932", input);
 |     //return CodeToUTF8("CP932", input);
 | ||||||
| 	return CodeToUTF8("SJIS", input); |     return CodeToUTF8("SJIS", input); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string UTF16ToUTF8(const std::wstring& input) | std::string UTF16ToUTF8(const std::wstring& input) | ||||||
| { | { | ||||||
| 	std::string result = |     std::string result = | ||||||
| 	//	CodeToUTF8("UCS-2", input);
 |     //    CodeToUTF8("UCS-2", input);
 | ||||||
| 	//	CodeToUTF8("UCS-2LE", input);
 |     //    CodeToUTF8("UCS-2LE", input);
 | ||||||
| 	//	CodeToUTF8("UTF-16", input);
 |     //    CodeToUTF8("UTF-16", input);
 | ||||||
| 		CodeToUTF8("UTF-16LE", input); |         CodeToUTF8("UTF-16LE", input); | ||||||
| 
 | 
 | ||||||
| 	// TODO: why is this needed?
 |     // TODO: why is this needed?
 | ||||||
| 	result.erase(std::remove(result.begin(), result.end(), 0x00), result.end()); |     result.erase(std::remove(result.begin(), result.end(), 0x00), result.end()); | ||||||
| 	return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -21,10 +21,10 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar | ||||||
| template<size_t Count> | template<size_t Count> | ||||||
| inline void CharArrayFromFormat(char (& out)[Count], const char* format, ...) | inline void CharArrayFromFormat(char (& out)[Count], const char* format, ...) | ||||||
| { | { | ||||||
| 	va_list args; |     va_list args; | ||||||
| 	va_start(args, format); |     va_start(args, format); | ||||||
| 	CharArrayFromFormatV(out, Count, format, args); |     CharArrayFromFormatV(out, Count, format, args); | ||||||
| 	va_end(args); |     va_end(args); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Good
 | // Good
 | ||||||
|  | @ -37,15 +37,15 @@ std::string StripQuotes(const std::string &s); | ||||||
| template <typename I> | template <typename I> | ||||||
| std::string ThousandSeparate(I value, int spaces = 0) | std::string ThousandSeparate(I value, int spaces = 0) | ||||||
| { | { | ||||||
| 	std::ostringstream oss; |     std::ostringstream oss; | ||||||
| 
 | 
 | ||||||
| // std::locale("") seems to be broken on many platforms
 | // std::locale("") seems to be broken on many platforms
 | ||||||
| #if defined _WIN32 || (defined __linux__ && !defined __clang__) | #if defined _WIN32 || (defined __linux__ && !defined __clang__) | ||||||
| 	oss.imbue(std::locale("")); |     oss.imbue(std::locale("")); | ||||||
| #endif | #endif | ||||||
| 	oss << std::setw(spaces) << value; |     oss << std::setw(spaces) << value; | ||||||
| 
 | 
 | ||||||
| 	return oss.str(); |     return oss.str(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string StringFromInt(int value); | std::string StringFromInt(int value); | ||||||
|  | @ -57,16 +57,16 @@ bool TryParse(const std::string &str, u32 *output); | ||||||
| template <typename N> | template <typename N> | ||||||
| static bool TryParse(const std::string &str, N *const output) | static bool TryParse(const std::string &str, N *const output) | ||||||
| { | { | ||||||
| 	std::istringstream iss(str); |     std::istringstream iss(str); | ||||||
|      |      | ||||||
| 	N tmp = 0; |     N tmp = 0; | ||||||
| 	if (iss >> tmp) |     if (iss >> tmp) | ||||||
| 	{ |     { | ||||||
| 		*output = tmp; |         *output = tmp; | ||||||
| 		return true; |         return true; | ||||||
| 	} |     } | ||||||
| 	else |     else | ||||||
| 		return false; |         return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TODO: kill this
 | // TODO: kill this
 | ||||||
|  |  | ||||||
|  | @ -63,426 +63,426 @@ | ||||||
| 
 | 
 | ||||||
| template <typename T, typename F> | template <typename T, typename F> | ||||||
| struct swap_struct_t { | struct swap_struct_t { | ||||||
| 	typedef swap_struct_t<T, F> swapped_t; |     typedef swap_struct_t<T, F> swapped_t; | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
| 	T value; |     T value; | ||||||
| 
 | 
 | ||||||
| 	static T swap(T v) { |     static T swap(T v) { | ||||||
| 		return F::swap(v); |         return F::swap(v); | ||||||
| 	} |     } | ||||||
| public: | public: | ||||||
| 	T const swap() const { |     T const swap() const { | ||||||
| 		return swap(value); |         return swap(value); | ||||||
| 
 | 
 | ||||||
| 	} |     } | ||||||
| 	swap_struct_t() : value((T)0) {} |     swap_struct_t() : value((T)0) {} | ||||||
| 	swap_struct_t(const T &v): value(swap(v)) {} |     swap_struct_t(const T &v): value(swap(v)) {} | ||||||
| 
 | 
 | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t& operator=(const S &source) { |     swapped_t& operator=(const S &source) { | ||||||
| 		value = swap((T)source); |         value = swap((T)source); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	operator long() const { return (long)swap(); }	 |     operator long() const { return (long)swap(); }     | ||||||
| 	operator s8() const { return (s8)swap(); } |     operator s8() const { return (s8)swap(); } | ||||||
| 	operator u8() const { return (u8)swap(); } |     operator u8() const { return (u8)swap(); } | ||||||
| 	operator s16() const { return (s16)swap(); } |     operator s16() const { return (s16)swap(); } | ||||||
| 	operator u16() const { return (u16)swap(); } |     operator u16() const { return (u16)swap(); } | ||||||
| 	operator s32() const { return (s32)swap(); } |     operator s32() const { return (s32)swap(); } | ||||||
| 	operator u32() const { return (u32)swap(); } |     operator u32() const { return (u32)swap(); } | ||||||
| 	operator s64() const { return (s64)swap(); } |     operator s64() const { return (s64)swap(); } | ||||||
| 	operator u64() const { return (u64)swap(); } |     operator u64() const { return (u64)swap(); } | ||||||
| 	operator float() const { return (float)swap(); } |     operator float() const { return (float)swap(); } | ||||||
| 	operator double() const { return (double)swap(); } |     operator double() const { return (double)swap(); } | ||||||
| 
 | 
 | ||||||
| 	// +v
 |     // +v
 | ||||||
| 	swapped_t operator +() const { |     swapped_t operator +() const { | ||||||
| 		return +swap(); |         return +swap(); | ||||||
| 	} |     } | ||||||
| 	// -v
 |     // -v
 | ||||||
| 	swapped_t operator -() const { |     swapped_t operator -() const { | ||||||
| 		return -swap(); |         return -swap(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// v / 5
 |     // v / 5
 | ||||||
| 	swapped_t operator/(const swapped_t &i) const { |     swapped_t operator/(const swapped_t &i) const { | ||||||
| 		return swap() / i.swap(); |         return swap() / i.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t operator/(const S &i) const { |     swapped_t operator/(const S &i) const { | ||||||
| 		return swap() / i; |         return swap() / i; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// v * 5
 |     // v * 5
 | ||||||
| 	swapped_t operator*(const swapped_t &i) const { |     swapped_t operator*(const swapped_t &i) const { | ||||||
| 		return swap() * i.swap(); |         return swap() * i.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t operator*(const S &i) const { |     swapped_t operator*(const S &i) const { | ||||||
| 		return swap() * i; |         return swap() * i; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// v + 5
 |     // v + 5
 | ||||||
| 	swapped_t operator+(const swapped_t &i) const { |     swapped_t operator+(const swapped_t &i) const { | ||||||
| 		return swap() + i.swap(); |         return swap() + i.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t operator+(const S &i) const { |     swapped_t operator+(const S &i) const { | ||||||
| 		return swap() + (T)i; |         return swap() + (T)i; | ||||||
| 	} |     } | ||||||
| 	// v - 5
 |     // v - 5
 | ||||||
| 	swapped_t operator-(const swapped_t &i) const { |     swapped_t operator-(const swapped_t &i) const { | ||||||
| 		return swap() - i.swap(); |         return swap() - i.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t operator-(const S &i) const { |     swapped_t operator-(const S &i) const { | ||||||
| 		return swap() - (T)i; |         return swap() - (T)i; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// v += 5
 |     // v += 5
 | ||||||
| 	swapped_t& operator+=(const swapped_t &i) { |     swapped_t& operator+=(const swapped_t &i) { | ||||||
| 		value = swap(swap() + i.swap()); |         value = swap(swap() + i.swap()); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t& operator+=(const S &i) { |     swapped_t& operator+=(const S &i) { | ||||||
| 		value = swap(swap() + (T)i); |         value = swap(swap() + (T)i); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 	// v -= 5
 |     // v -= 5
 | ||||||
| 	swapped_t& operator-=(const swapped_t &i) { |     swapped_t& operator-=(const swapped_t &i) { | ||||||
| 		value = swap(swap() - i.swap()); |         value = swap(swap() - i.swap()); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t& operator-=(const S &i) { |     swapped_t& operator-=(const S &i) { | ||||||
| 		value = swap(swap() - (T)i); |         value = swap(swap() - (T)i); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// ++v
 |     // ++v
 | ||||||
| 	swapped_t& operator++() { |     swapped_t& operator++() { | ||||||
| 		value = swap(swap()+1); |         value = swap(swap()+1); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 	// --v
 |     // --v
 | ||||||
| 	swapped_t& operator--()  { |     swapped_t& operator--()  { | ||||||
| 		value = swap(swap()-1); |         value = swap(swap()-1); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// v++
 |     // v++
 | ||||||
| 	swapped_t operator++(int) { |     swapped_t operator++(int) { | ||||||
| 		swapped_t old = *this; |         swapped_t old = *this; | ||||||
| 		value = swap(swap()+1); |         value = swap(swap()+1); | ||||||
| 		return old; |         return old; | ||||||
| 	} |     } | ||||||
| 	// v--
 |     // v--
 | ||||||
| 	swapped_t operator--(int) { |     swapped_t operator--(int) { | ||||||
| 		swapped_t old = *this; |         swapped_t old = *this; | ||||||
| 		value = swap(swap()-1); |         value = swap(swap()-1); | ||||||
| 		return old; |         return old; | ||||||
| 	} |     } | ||||||
| 	// Comparaison
 |     // Comparaison
 | ||||||
| 	// v == i
 |     // v == i
 | ||||||
| 	bool operator==(const swapped_t &i) const { |     bool operator==(const swapped_t &i) const { | ||||||
| 		return swap() == i.swap(); |         return swap() == i.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	bool operator==(const S &i) const { |     bool operator==(const S &i) const { | ||||||
| 		return swap() == i; |         return swap() == i; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// v != i
 |     // v != i
 | ||||||
| 	bool operator!=(const swapped_t &i) const { |     bool operator!=(const swapped_t &i) const { | ||||||
| 		return swap() != i.swap(); |         return swap() != i.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	bool operator!=(const S &i) const { |     bool operator!=(const S &i) const { | ||||||
| 		return swap() != i; |         return swap() != i; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// v > i
 |     // v > i
 | ||||||
| 	bool operator>(const swapped_t &i) const { |     bool operator>(const swapped_t &i) const { | ||||||
| 		return swap() > i.swap(); |         return swap() > i.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	bool operator>(const S &i) const { |     bool operator>(const S &i) const { | ||||||
| 		return swap() > i; |         return swap() > i; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// v < i
 |     // v < i
 | ||||||
| 	bool operator<(const swapped_t &i) const { |     bool operator<(const swapped_t &i) const { | ||||||
| 		return swap() < i.swap(); |         return swap() < i.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	bool operator<(const S &i) const { |     bool operator<(const S &i) const { | ||||||
| 		return swap() < i; |         return swap() < i; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// v >= i
 |     // v >= i
 | ||||||
| 	bool operator>=(const swapped_t &i) const { |     bool operator>=(const swapped_t &i) const { | ||||||
| 		return swap() >= i.swap(); |         return swap() >= i.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	bool operator>=(const S &i) const { |     bool operator>=(const S &i) const { | ||||||
| 		return swap() >= i; |         return swap() >= i; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// v <= i
 |     // v <= i
 | ||||||
| 	bool operator<=(const swapped_t &i) const { |     bool operator<=(const swapped_t &i) const { | ||||||
| 		return swap() <= i.swap(); |         return swap() <= i.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	bool operator<=(const S &i) const { |     bool operator<=(const S &i) const { | ||||||
| 		return swap() <= i; |         return swap() <= i; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// logical
 |     // logical
 | ||||||
| 	swapped_t operator !() const { |     swapped_t operator !() const { | ||||||
| 		return !swap(); |         return !swap(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// bitmath
 |     // bitmath
 | ||||||
| 	swapped_t operator ~() const { |     swapped_t operator ~() const { | ||||||
| 		return ~swap(); |         return ~swap(); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	swapped_t operator &(const swapped_t &b) const { |     swapped_t operator &(const swapped_t &b) const { | ||||||
| 		return swap() & b.swap(); |         return swap() & b.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t operator &(const S &b) const { |     swapped_t operator &(const S &b) const { | ||||||
| 		return swap() & b; |         return swap() & b; | ||||||
| 	} |     } | ||||||
| 	swapped_t& operator &=(const swapped_t &b) { |     swapped_t& operator &=(const swapped_t &b) { | ||||||
| 		value = swap(swap() & b.swap()); |         value = swap(swap() & b.swap()); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t& operator &=(const S b) { |     swapped_t& operator &=(const S b) { | ||||||
| 		value = swap(swap() & b); |         value = swap(swap() & b); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	swapped_t operator |(const swapped_t &b) const { |     swapped_t operator |(const swapped_t &b) const { | ||||||
| 		return swap() | b.swap(); |         return swap() | b.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t operator |(const S &b) const { |     swapped_t operator |(const S &b) const { | ||||||
| 		return swap() | b; |         return swap() | b; | ||||||
| 	} |     } | ||||||
| 	swapped_t& operator |=(const swapped_t &b) { |     swapped_t& operator |=(const swapped_t &b) { | ||||||
| 		value = swap(swap() | b.swap()); |         value = swap(swap() | b.swap()); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t& operator |=(const S &b) { |     swapped_t& operator |=(const S &b) { | ||||||
| 		value = swap(swap() | b); |         value = swap(swap() | b); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	swapped_t operator ^(const swapped_t &b) const { |     swapped_t operator ^(const swapped_t &b) const { | ||||||
| 		return swap() ^ b.swap(); |         return swap() ^ b.swap(); | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t operator ^(const S &b) const { |     swapped_t operator ^(const S &b) const { | ||||||
| 		return swap() ^ b; |         return swap() ^ b; | ||||||
| 	} |     } | ||||||
| 	swapped_t& operator ^=(const swapped_t &b) { |     swapped_t& operator ^=(const swapped_t &b) { | ||||||
| 		value = swap(swap() ^ b.swap()); |         value = swap(swap() ^ b.swap()); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t& operator ^=(const S &b) { |     swapped_t& operator ^=(const S &b) { | ||||||
| 		value = swap(swap() ^ b); |         value = swap(swap() ^ b); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t operator <<(const S &b) const { |     swapped_t operator <<(const S &b) const { | ||||||
| 		return swap() << b; |         return swap() << b; | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t& operator <<=(const S &b) const { |     swapped_t& operator <<=(const S &b) const { | ||||||
| 		value = swap(swap() << b); |         value = swap(swap() << b); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t operator >>(const S &b) const { |     swapped_t operator >>(const S &b) const { | ||||||
| 		return swap() >> b; |         return swap() >> b; | ||||||
| 	} |     } | ||||||
| 	template <typename S> |     template <typename S> | ||||||
| 	swapped_t& operator >>=(const S &b) const { |     swapped_t& operator >>=(const S &b) const { | ||||||
| 		value = swap(swap() >> b); |         value = swap(swap() >> b); | ||||||
| 		return *this; |         return *this; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	// Member
 |     // Member
 | ||||||
| 	/** todo **/ |     /** todo **/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// Arithmetics
 |     // Arithmetics
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend S operator+(const S &p, const swapped_t v); |     friend S operator+(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend S operator-(const S &p, const swapped_t v); |     friend S operator-(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend S operator/(const S &p, const swapped_t v); |     friend S operator/(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend S operator*(const S &p, const swapped_t v); |     friend S operator*(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend S operator%(const S &p, const swapped_t v); |     friend S operator%(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	// Arithmetics + assignements
 |     // Arithmetics + assignements
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend S operator+=(const S &p, const swapped_t v); |     friend S operator+=(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend S operator-=(const S &p, const swapped_t v); |     friend S operator-=(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	// Bitmath
 |     // Bitmath
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend S operator&(const S &p, const swapped_t v); |     friend S operator&(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	// Comparison
 |     // Comparison
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend bool operator<(const S &p, const swapped_t v); |     friend bool operator<(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend bool operator>(const S &p, const swapped_t v); |     friend bool operator>(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend bool operator<=(const S &p, const swapped_t v); |     friend bool operator<=(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend bool operator>=(const S &p, const swapped_t v); |     friend bool operator>=(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend bool operator!=(const S &p, const swapped_t v); |     friend bool operator!=(const S &p, const swapped_t v); | ||||||
| 
 | 
 | ||||||
| 	template <typename S, typename T2, typename F2> |     template <typename S, typename T2, typename F2> | ||||||
| 	friend bool operator==(const S &p, const swapped_t v); |     friend bool operator==(const S &p, const swapped_t v); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| // Arithmetics
 | // Arithmetics
 | ||||||
| template <typename S, typename T, typename F> | template <typename S, typename T, typename F> | ||||||
| S operator+(const S &i, const swap_struct_t<T, F> v) { | 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> | template <typename S, typename T, typename F> | ||||||
| S operator-(const S &i, const swap_struct_t<T, F> v) { | 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> | template <typename S, typename T, typename F> | ||||||
| S operator/(const S &i, const swap_struct_t<T, F> v) { | 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> | template <typename S, typename T, typename F> | ||||||
| S operator*(const S &i, const swap_struct_t<T, F> v) { | 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> | template <typename S, typename T, typename F> | ||||||
| S operator%(const S &i, const swap_struct_t<T, F> v) { | S operator%(const S &i, const swap_struct_t<T, F> v) { | ||||||
| 	return i % v.swap(); |     return i % v.swap(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Arithmetics + assignements
 | // Arithmetics + assignements
 | ||||||
| template <typename S, typename T, typename F> | template <typename S, typename T, typename F> | ||||||
| S &operator+=(S &i, const swap_struct_t<T, F> v) { | S &operator+=(S &i, const swap_struct_t<T, F> v) { | ||||||
| 	i += v.swap(); |     i += v.swap(); | ||||||
| 	return i; |     return i; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <typename S, typename T, typename F> | template <typename S, typename T, typename F> | ||||||
| S &operator-=(S &i, const swap_struct_t<T, F> v) { | S &operator-=(S &i, const swap_struct_t<T, F> v) { | ||||||
| 	i -= v.swap(); |     i -= v.swap(); | ||||||
| 	return i; |     return i; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Logical
 | // Logical
 | ||||||
| template <typename S, typename T, typename F> | template <typename S, typename T, typename F> | ||||||
| S operator&(const S &i, const swap_struct_t<T, F> v) { | 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> | template <typename S, typename T, typename F> | ||||||
| S operator&(const swap_struct_t<T, F> v, const S &i) { | S operator&(const swap_struct_t<T, F> v, const S &i) { | ||||||
| 	return (S)(v.swap() & i); |     return (S)(v.swap() & i); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| // Comparaison
 | // Comparaison
 | ||||||
| template <typename S, typename T, typename F> | template <typename S, typename T, typename F> | ||||||
| bool operator<(const S &p, const swap_struct_t<T, F> v) { | 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> | template <typename S, typename T, typename F> | ||||||
| bool operator>(const S &p, const swap_struct_t<T, F> v) { | 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> | template <typename S, typename T, typename F> | ||||||
| bool operator<=(const S &p, const swap_struct_t<T, F> v) { | 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> | template <typename S, typename T, typename F> | ||||||
| bool operator>=(const S &p, const swap_struct_t<T, F> v) { | 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> | template <typename S, typename T, typename F> | ||||||
| bool operator!=(const S &p, const swap_struct_t<T, F> v) { | 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> | template <typename S, typename T, typename F> | ||||||
| bool operator==(const S &p, const swap_struct_t<T, F> v) { | bool operator==(const S &p, const swap_struct_t<T, F> v) { | ||||||
| 	return p == v.swap(); |     return p == v.swap(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| struct swap_64_t { | struct swap_64_t { | ||||||
| 	static T swap(T x) { |     static T swap(T x) { | ||||||
| 		return (T)bswap64(*(u64 *)&x); |         return (T)bswap64(*(u64 *)&x); | ||||||
| 	} |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| struct swap_32_t { | struct swap_32_t { | ||||||
| 	static T swap(T x) { |     static T swap(T x) { | ||||||
| 		return (T)bswap32(*(u32 *)&x); |         return (T)bswap32(*(u32 *)&x); | ||||||
| 	} |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| struct swap_16_t { | struct swap_16_t { | ||||||
| 	static T swap(T x) { |     static T swap(T x) { | ||||||
| 		return (T)bswap16(*(u16 *)&x); |         return (T)bswap16(*(u16 *)&x); | ||||||
| 	} |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| struct swap_float_t { | struct swap_float_t { | ||||||
| 	static T swap(T x) { |     static T swap(T x) { | ||||||
| 		return (T)bswapf(*(float *)&x); |         return (T)bswapf(*(float *)&x); | ||||||
| 	} |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| struct swap_double_t { | struct swap_double_t { | ||||||
| 	static T swap(T x) { |     static T swap(T x) { | ||||||
| 		return (T)bswapd(*(double *)&x); |         return (T)bswapd(*(double *)&x); | ||||||
| 	} |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #if COMMON_LITTLE_ENDIAN | #if COMMON_LITTLE_ENDIAN | ||||||
|  |  | ||||||
|  | @ -21,11 +21,11 @@ namespace Common | ||||||
| int CurrentThreadId() | int CurrentThreadId() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	return GetCurrentThreadId(); |     return GetCurrentThreadId(); | ||||||
| #elif defined __APPLE__ | #elif defined __APPLE__ | ||||||
| 	return mach_thread_self(); |     return mach_thread_self(); | ||||||
| #else | #else | ||||||
| 	return 0; |     return 0; | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|      |      | ||||||
|  | @ -33,23 +33,23 @@ int CurrentThreadId() | ||||||
| 
 | 
 | ||||||
| void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) | void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) | ||||||
| { | { | ||||||
| 	SetThreadAffinityMask(thread, mask); |     SetThreadAffinityMask(thread, mask); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SetCurrentThreadAffinity(u32 mask) | void SetCurrentThreadAffinity(u32 mask) | ||||||
| { | { | ||||||
| 	SetThreadAffinityMask(GetCurrentThread(), mask); |     SetThreadAffinityMask(GetCurrentThread(), mask); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Supporting functions
 | // Supporting functions
 | ||||||
| void SleepCurrentThread(int ms) | void SleepCurrentThread(int ms) | ||||||
| { | { | ||||||
| 	Sleep(ms); |     Sleep(ms); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SwitchCurrentThread() | void SwitchCurrentThread() | ||||||
| { | { | ||||||
| 	SwitchToThread(); |     SwitchToThread(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Sets the debugger-visible name of the current thread.
 | // Sets the debugger-visible name of the current thread.
 | ||||||
|  | @ -60,29 +60,29 @@ void SwitchCurrentThread() | ||||||
| // http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.100).aspx
 | // http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.100).aspx
 | ||||||
| void SetCurrentThreadName(const char* szThreadName) | void SetCurrentThreadName(const char* szThreadName) | ||||||
| { | { | ||||||
| 	static const DWORD MS_VC_EXCEPTION = 0x406D1388; |     static const DWORD MS_VC_EXCEPTION = 0x406D1388; | ||||||
| 
 | 
 | ||||||
| 	#pragma pack(push,8) |     #pragma pack(push,8) | ||||||
| 	struct THREADNAME_INFO |     struct THREADNAME_INFO | ||||||
| 	{ |     { | ||||||
| 		DWORD dwType; // must be 0x1000
 |         DWORD dwType; // must be 0x1000
 | ||||||
| 		LPCSTR szName; // pointer to name (in user addr space)
 |         LPCSTR szName; // pointer to name (in user addr space)
 | ||||||
| 		DWORD dwThreadID; // thread ID (-1=caller thread)
 |         DWORD dwThreadID; // thread ID (-1=caller thread)
 | ||||||
| 		DWORD dwFlags; // reserved for future use, must be zero
 |         DWORD dwFlags; // reserved for future use, must be zero
 | ||||||
| 	} info; |     } info; | ||||||
| 	#pragma pack(pop) |     #pragma pack(pop) | ||||||
| 
 | 
 | ||||||
| 	info.dwType = 0x1000; |     info.dwType = 0x1000; | ||||||
| 	info.szName = szThreadName; |     info.szName = szThreadName; | ||||||
| 	info.dwThreadID = -1; //dwThreadID;
 |     info.dwThreadID = -1; //dwThreadID;
 | ||||||
| 	info.dwFlags = 0; |     info.dwFlags = 0; | ||||||
| 
 | 
 | ||||||
| 	__try |     __try | ||||||
| 	{ |     { | ||||||
| 		RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info); |         RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info); | ||||||
| 	} |     } | ||||||
| 	__except(EXCEPTION_CONTINUE_EXECUTION) |     __except(EXCEPTION_CONTINUE_EXECUTION) | ||||||
| 	{} |     {} | ||||||
| } | } | ||||||
|      |      | ||||||
| #else // !WIN32, so must be POSIX threads
 | #else // !WIN32, so must be POSIX threads
 | ||||||
|  | @ -90,41 +90,41 @@ void SetCurrentThreadName(const char* szThreadName) | ||||||
| void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) | void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) | ||||||
| { | { | ||||||
| #ifdef __APPLE__ | #ifdef __APPLE__ | ||||||
| 	thread_policy_set(pthread_mach_thread_np(thread), |     thread_policy_set(pthread_mach_thread_np(thread), | ||||||
| 		THREAD_AFFINITY_POLICY, (integer_t *)&mask, 1); |         THREAD_AFFINITY_POLICY, (integer_t *)&mask, 1); | ||||||
| #elif (defined __linux__ || defined BSD4_4) && !(defined ANDROID) | #elif (defined __linux__ || defined BSD4_4) && !(defined ANDROID) | ||||||
| 	cpu_set_t cpu_set; |     cpu_set_t cpu_set; | ||||||
| 	CPU_ZERO(&cpu_set); |     CPU_ZERO(&cpu_set); | ||||||
| 
 | 
 | ||||||
| 	for (int i = 0; i != sizeof(mask) * 8; ++i) |     for (int i = 0; i != sizeof(mask) * 8; ++i) | ||||||
| 		if ((mask >> i) & 1) |         if ((mask >> i) & 1) | ||||||
| 			CPU_SET(i, &cpu_set); |             CPU_SET(i, &cpu_set); | ||||||
| 
 | 
 | ||||||
| 	pthread_setaffinity_np(thread, sizeof(cpu_set), &cpu_set); |     pthread_setaffinity_np(thread, sizeof(cpu_set), &cpu_set); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SetCurrentThreadAffinity(u32 mask) | void SetCurrentThreadAffinity(u32 mask) | ||||||
| { | { | ||||||
| 	SetThreadAffinity(pthread_self(), mask); |     SetThreadAffinity(pthread_self(), mask); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SleepCurrentThread(int ms) | void SleepCurrentThread(int ms) | ||||||
| { | { | ||||||
| 	usleep(1000 * ms); |     usleep(1000 * ms); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SwitchCurrentThread() | void SwitchCurrentThread() | ||||||
| { | { | ||||||
| 	usleep(1000 * 1); |     usleep(1000 * 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SetCurrentThreadName(const char* szThreadName) | void SetCurrentThreadName(const char* szThreadName) | ||||||
| { | { | ||||||
| #ifdef __APPLE__ | #ifdef __APPLE__ | ||||||
| 	pthread_setname_np(szThreadName); |     pthread_setname_np(szThreadName); | ||||||
| #else | #else | ||||||
| 	pthread_setname_np(pthread_self(), szThreadName); |     pthread_setname_np(pthread_self(), szThreadName); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -36,117 +36,117 @@ void SetCurrentThreadAffinity(u32 mask); | ||||||
| class Event | class Event | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	Event() |     Event() | ||||||
| 		: is_set(false) |         : is_set(false) | ||||||
| 	{}; |     {}; | ||||||
| 
 | 
 | ||||||
| 	void Set() |     void Set() | ||||||
| 	{ |     { | ||||||
| 		std::lock_guard<std::mutex> lk(m_mutex); |         std::lock_guard<std::mutex> lk(m_mutex); | ||||||
| 		if (!is_set) |         if (!is_set) | ||||||
| 		{ |         { | ||||||
| 			is_set = true; |             is_set = true; | ||||||
| 			m_condvar.notify_one(); |             m_condvar.notify_one(); | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void Wait() |     void Wait() | ||||||
| 	{ |     { | ||||||
| 		std::unique_lock<std::mutex> lk(m_mutex); |         std::unique_lock<std::mutex> lk(m_mutex); | ||||||
| 		m_condvar.wait(lk, IsSet(this)); |         m_condvar.wait(lk, IsSet(this)); | ||||||
| 		is_set = false; |         is_set = false; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| 	void Reset() |     void Reset() | ||||||
| 	{ |     { | ||||||
| 		std::unique_lock<std::mutex> lk(m_mutex); |         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
 |         // no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration
 | ||||||
| 		is_set = false; |         is_set = false; | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	class IsSet |     class IsSet | ||||||
| 	{ |     { | ||||||
| 	public: |     public: | ||||||
| 		IsSet(const Event* ev) |         IsSet(const Event* ev) | ||||||
| 			: m_event(ev) |             : m_event(ev) | ||||||
| 		{} |         {} | ||||||
| 
 | 
 | ||||||
| 		bool operator()() |         bool operator()() | ||||||
| 		{ |         { | ||||||
| 			return m_event->is_set; |             return m_event->is_set; | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 	private: |     private: | ||||||
| 		const Event* const m_event; |         const Event* const m_event; | ||||||
| 	}; |     }; | ||||||
| 
 | 
 | ||||||
| 	volatile bool is_set; |     volatile bool is_set; | ||||||
| 	std::condition_variable m_condvar; |     std::condition_variable m_condvar; | ||||||
| 	std::mutex m_mutex; |     std::mutex m_mutex; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // TODO: doesn't work on windows with (count > 2)
 | // TODO: doesn't work on windows with (count > 2)
 | ||||||
| class Barrier | class Barrier | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	Barrier(size_t count) |     Barrier(size_t count) | ||||||
| 		: m_count(count), m_waiting(0) |         : m_count(count), m_waiting(0) | ||||||
| 	{} |     {} | ||||||
| 
 | 
 | ||||||
| 	// block until "count" threads call Sync()
 |     // block until "count" threads call Sync()
 | ||||||
| 	bool Sync() |     bool Sync() | ||||||
| 	{ |     { | ||||||
| 		std::unique_lock<std::mutex> lk(m_mutex); |         std::unique_lock<std::mutex> lk(m_mutex); | ||||||
| 
 | 
 | ||||||
| 		// TODO: broken when next round of Sync()s
 |         // TODO: broken when next round of Sync()s
 | ||||||
| 		// is entered before all waiting threads return from the notify_all
 |         // is entered before all waiting threads return from the notify_all
 | ||||||
| 
 | 
 | ||||||
| 		if (m_count == ++m_waiting) |         if (m_count == ++m_waiting) | ||||||
| 		{ |         { | ||||||
| 			m_waiting = 0; |             m_waiting = 0; | ||||||
| 			m_condvar.notify_all(); |             m_condvar.notify_all(); | ||||||
| 			return true; |             return true; | ||||||
| 		} |         } | ||||||
| 		else |         else | ||||||
| 		{ |         { | ||||||
| 			m_condvar.wait(lk, IsDoneWating(this)); |             m_condvar.wait(lk, IsDoneWating(this)); | ||||||
| 			return false; |             return false; | ||||||
| 		} |         } | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	class IsDoneWating |     class IsDoneWating | ||||||
| 	{ |     { | ||||||
| 	public: |     public: | ||||||
| 		IsDoneWating(const Barrier* bar) |         IsDoneWating(const Barrier* bar) | ||||||
| 			: m_bar(bar) |             : m_bar(bar) | ||||||
| 		{} |         {} | ||||||
| 
 | 
 | ||||||
| 		bool operator()() |         bool operator()() | ||||||
| 		{ |         { | ||||||
| 			return (0 == m_bar->m_waiting); |             return (0 == m_bar->m_waiting); | ||||||
| 		} |         } | ||||||
| 
 | 
 | ||||||
| 	private: |     private: | ||||||
| 		const Barrier* const m_bar; |         const Barrier* const m_bar; | ||||||
| 	}; |     }; | ||||||
| 
 | 
 | ||||||
| 	std::condition_variable m_condvar; |     std::condition_variable m_condvar; | ||||||
| 	std::mutex m_mutex; |     std::mutex m_mutex; | ||||||
| 	const size_t m_count; |     const size_t m_count; | ||||||
| 	volatile size_t m_waiting; |     volatile size_t m_waiting; | ||||||
| }; | }; | ||||||
|      |      | ||||||
| void SleepCurrentThread(int ms); | 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
 | // Use this function during a spin-wait to make the current thread
 | ||||||
| // relax while another thread is working. This may be more efficient
 | // relax while another thread is working. This may be more efficient
 | ||||||
| // than using events because event functions use kernel calls.
 | // than using events because event functions use kernel calls.
 | ||||||
| inline void YieldCPU() | inline void YieldCPU() | ||||||
| { | { | ||||||
| 	std::this_thread::yield(); |     std::this_thread::yield(); | ||||||
| } | } | ||||||
|      |      | ||||||
| void SetCurrentThreadName(const char *name); | void SetCurrentThreadName(const char *name); | ||||||
|  |  | ||||||
|  | @ -24,23 +24,23 @@ | ||||||
| 
 | 
 | ||||||
| class ThunkManager : public Gen::XCodeBlock | class ThunkManager : public Gen::XCodeBlock | ||||||
| { | { | ||||||
| 	std::map<void *, const u8 *> thunks; |     std::map<void *, const u8 *> thunks; | ||||||
| 
 | 
 | ||||||
| 	const u8 *save_regs; |     const u8 *save_regs; | ||||||
| 	const u8 *load_regs; |     const u8 *load_regs; | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
| 	ThunkManager() { |     ThunkManager() { | ||||||
| 		Init(); |         Init(); | ||||||
| 	} |     } | ||||||
| 	~ThunkManager() { |     ~ThunkManager() { | ||||||
| 		Shutdown(); |         Shutdown(); | ||||||
| 	} |     } | ||||||
| 	void *ProtectFunction(void *function, int num_params); |     void *ProtectFunction(void *function, int num_params); | ||||||
| private: | private: | ||||||
| 	void Init(); |     void Init(); | ||||||
| 	void Shutdown(); |     void Shutdown(); | ||||||
| 	void Reset(); |     void Reset(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // _THUNK_H_
 | #endif // _THUNK_H_
 | ||||||
|  |  | ||||||
|  | @ -22,11 +22,11 @@ namespace Common | ||||||
| u32 Timer::GetTimeMs() | u32 Timer::GetTimeMs() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	return timeGetTime(); |     return timeGetTime(); | ||||||
| #else | #else | ||||||
| 	struct timeval t; |     struct timeval t; | ||||||
| 	(void)gettimeofday(&t, NULL); |     (void)gettimeofday(&t, NULL); | ||||||
| 	return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); |     return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -36,31 +36,31 @@ u32 Timer::GetTimeMs() | ||||||
| 
 | 
 | ||||||
| // Set initial values for the class
 | // Set initial values for the class
 | ||||||
| Timer::Timer() | 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
 | // Write the starting time
 | ||||||
| void Timer::Start() | void Timer::Start() | ||||||
| { | { | ||||||
| 	m_StartTime = GetTimeMs(); |     m_StartTime = GetTimeMs(); | ||||||
| 	m_Running = true; |     m_Running = true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Stop the timer
 | // Stop the timer
 | ||||||
| void Timer::Stop() | void Timer::Stop() | ||||||
| { | { | ||||||
| 	// Write the final time
 |     // Write the final time
 | ||||||
| 	m_LastTime = GetTimeMs(); |     m_LastTime = GetTimeMs(); | ||||||
| 	m_Running = false; |     m_Running = false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Update the last time variable
 | // Update the last time variable
 | ||||||
| void Timer::Update() | void Timer::Update() | ||||||
| { | { | ||||||
| 	m_LastTime = GetTimeMs(); |     m_LastTime = GetTimeMs(); | ||||||
| 	//TODO(ector) - QPF
 |     //TODO(ector) - QPF
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // -------------------------------------
 | // -------------------------------------
 | ||||||
|  | @ -70,125 +70,125 @@ void Timer::Update() | ||||||
| // Get the number of milliseconds since the last Update()
 | // Get the number of milliseconds since the last Update()
 | ||||||
| u64 Timer::GetTimeDifference() | u64 Timer::GetTimeDifference() | ||||||
| { | { | ||||||
| 	return GetTimeMs() - m_LastTime; |     return GetTimeMs() - m_LastTime; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Add the time difference since the last Update() to the starting time.
 | // Add the time difference since the last Update() to the starting time.
 | ||||||
| // This is used to compensate for a paused game.
 | // This is used to compensate for a paused game.
 | ||||||
| void Timer::AddTimeDifference() | void Timer::AddTimeDifference() | ||||||
| { | { | ||||||
| 	m_StartTime += GetTimeDifference(); |     m_StartTime += GetTimeDifference(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Get the time elapsed since the Start()
 | // Get the time elapsed since the Start()
 | ||||||
| u64 Timer::GetTimeElapsed() | u64 Timer::GetTimeElapsed() | ||||||
| { | { | ||||||
| 	// If we have not started yet, return 1 (because then I don't
 |     // If we have not started yet, return 1 (because then I don't
 | ||||||
| 	// have to change the FPS calculation in CoreRerecording.cpp .
 |     // have to change the FPS calculation in CoreRerecording.cpp .
 | ||||||
| 	if (m_StartTime == 0) return 1; |     if (m_StartTime == 0) return 1; | ||||||
| 
 | 
 | ||||||
| 	// Return the final timer time if the timer is stopped
 |     // Return the final timer time if the timer is stopped
 | ||||||
| 	if (!m_Running) return (m_LastTime - m_StartTime); |     if (!m_Running) return (m_LastTime - m_StartTime); | ||||||
| 
 | 
 | ||||||
| 	return (GetTimeMs() - m_StartTime); |     return (GetTimeMs() - m_StartTime); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Get the formatted time elapsed since the Start()
 | // Get the formatted time elapsed since the Start()
 | ||||||
| std::string Timer::GetTimeElapsedFormatted() const | std::string Timer::GetTimeElapsedFormatted() const | ||||||
| { | { | ||||||
| 	// If we have not started yet, return zero
 |     // If we have not started yet, return zero
 | ||||||
| 	if (m_StartTime == 0) |     if (m_StartTime == 0) | ||||||
| 		return "00:00:00:000"; |         return "00:00:00:000"; | ||||||
| 
 | 
 | ||||||
| 	// The number of milliseconds since the start.
 |     // The number of milliseconds since the start.
 | ||||||
| 	// Use a different value if the timer is stopped.
 |     // Use a different value if the timer is stopped.
 | ||||||
| 	u64 Milliseconds; |     u64 Milliseconds; | ||||||
| 	if (m_Running) |     if (m_Running) | ||||||
| 		Milliseconds = GetTimeMs() - m_StartTime; |         Milliseconds = GetTimeMs() - m_StartTime; | ||||||
| 	else |     else | ||||||
| 		Milliseconds = m_LastTime - m_StartTime; |         Milliseconds = m_LastTime - m_StartTime; | ||||||
| 	// Seconds
 |     // Seconds
 | ||||||
| 	u32 Seconds = (u32)(Milliseconds / 1000); |     u32 Seconds = (u32)(Milliseconds / 1000); | ||||||
| 	// Minutes
 |     // Minutes
 | ||||||
| 	u32 Minutes = Seconds / 60; |     u32 Minutes = Seconds / 60; | ||||||
| 	// Hours
 |     // Hours
 | ||||||
| 	u32 Hours = Minutes / 60; |     u32 Hours = Minutes / 60; | ||||||
| 
 | 
 | ||||||
| 	std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i", |     std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i", | ||||||
| 		Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000); |         Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000); | ||||||
| 	return TmpStr; |     return TmpStr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Get current time
 | // Get current time
 | ||||||
| void Timer::IncreaseResolution() | void Timer::IncreaseResolution() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	timeBeginPeriod(1); |     timeBeginPeriod(1); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Timer::RestoreResolution() | void Timer::RestoreResolution() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	timeEndPeriod(1); |     timeEndPeriod(1); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Get the number of seconds since January 1 1970
 | // Get the number of seconds since January 1 1970
 | ||||||
| u64 Timer::GetTimeSinceJan1970() | u64 Timer::GetTimeSinceJan1970() | ||||||
| { | { | ||||||
| 	time_t ltime; |     time_t ltime; | ||||||
| 	time(<ime); |     time(<ime); | ||||||
| 	return((u64)ltime); |     return((u64)ltime); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u64 Timer::GetLocalTimeSinceJan1970() | u64 Timer::GetLocalTimeSinceJan1970() | ||||||
| { | { | ||||||
| 	time_t sysTime, tzDiff, tzDST; |     time_t sysTime, tzDiff, tzDST; | ||||||
| 	struct tm * gmTime; |     struct tm * gmTime; | ||||||
| 
 | 
 | ||||||
| 	time(&sysTime); |     time(&sysTime); | ||||||
| 
 | 
 | ||||||
| 	// Account for DST where needed
 |     // Account for DST where needed
 | ||||||
| 	gmTime = localtime(&sysTime); |     gmTime = localtime(&sysTime); | ||||||
| 	if(gmTime->tm_isdst == 1) |     if(gmTime->tm_isdst == 1) | ||||||
| 		tzDST = 3600; |         tzDST = 3600; | ||||||
| 	else |     else | ||||||
| 		tzDST = 0; |         tzDST = 0; | ||||||
| 
 | 
 | ||||||
| 	// Lazy way to get local time in sec
 |     // Lazy way to get local time in sec
 | ||||||
| 	gmTime	= gmtime(&sysTime); |     gmTime    = gmtime(&sysTime); | ||||||
| 	tzDiff = sysTime - mktime(gmTime); |     tzDiff = sysTime - mktime(gmTime); | ||||||
| 
 | 
 | ||||||
| 	return (u64)(sysTime + tzDiff + tzDST); |     return (u64)(sysTime + tzDiff + tzDST); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Return the current time formatted as Minutes:Seconds:Milliseconds
 | // Return the current time formatted as Minutes:Seconds:Milliseconds
 | ||||||
| // in the form 00:00:000.
 | // in the form 00:00:000.
 | ||||||
| std::string Timer::GetTimeFormatted() | std::string Timer::GetTimeFormatted() | ||||||
| { | { | ||||||
| 	time_t sysTime; |     time_t sysTime; | ||||||
| 	struct tm * gmTime; |     struct tm * gmTime; | ||||||
| 	char formattedTime[13]; |     char formattedTime[13]; | ||||||
| 	char tmp[13]; |     char tmp[13]; | ||||||
| 
 | 
 | ||||||
| 	time(&sysTime); |     time(&sysTime); | ||||||
| 	gmTime = localtime(&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 | #ifdef _WIN32 | ||||||
| 	struct timeb tp; |     struct timeb tp; | ||||||
| 	(void)::ftime(&tp); |     (void)::ftime(&tp); | ||||||
| 	sprintf(formattedTime, "%s:%03i", tmp, tp.millitm); |     sprintf(formattedTime, "%s:%03i", tmp, tp.millitm); | ||||||
| #else | #else | ||||||
| 	struct timeval t; |     struct timeval t; | ||||||
| 	(void)gettimeofday(&t, NULL); |     (void)gettimeofday(&t, NULL); | ||||||
| 	sprintf(formattedTime, "%s:%03d", tmp, (int)(t.tv_usec / 1000)); |     sprintf(formattedTime, "%s:%03d", tmp, (int)(t.tv_usec / 1000)); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	return std::string(formattedTime); |     return std::string(formattedTime); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Returns a timestamp with decimals for precise time comparisons
 | // Returns a timestamp with decimals for precise time comparisons
 | ||||||
|  | @ -196,31 +196,31 @@ std::string Timer::GetTimeFormatted() | ||||||
| double Timer::GetDoubleTime() | double Timer::GetDoubleTime() | ||||||
| { | { | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	struct timeb tp; |     struct timeb tp; | ||||||
| 	(void)::ftime(&tp); |     (void)::ftime(&tp); | ||||||
| #else | #else | ||||||
| 	struct timeval t; |     struct timeval t; | ||||||
| 	(void)gettimeofday(&t, NULL); |     (void)gettimeofday(&t, NULL); | ||||||
| #endif | #endif | ||||||
| 	// Get continuous timestamp
 |     // Get continuous timestamp
 | ||||||
| 	u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); |     u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); | ||||||
| 
 | 
 | ||||||
| 	// Remove a few years. We only really want enough seconds to make
 |     // Remove a few years. We only really want enough seconds to make
 | ||||||
| 	// sure that we are detecting actual actions, perhaps 60 seconds is
 |     // sure that we are detecting actual actions, perhaps 60 seconds is
 | ||||||
| 	// enough really, but I leave a year of seconds anyway, in case the
 |     // enough really, but I leave a year of seconds anyway, in case the
 | ||||||
| 	// user's clock is incorrect or something like that.
 |     // user's clock is incorrect or something like that.
 | ||||||
| 	TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); |     TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); | ||||||
| 
 | 
 | ||||||
| 	// Make a smaller integer that fits in the double
 |     // Make a smaller integer that fits in the double
 | ||||||
| 	u32 Seconds = (u32)TmpSeconds; |     u32 Seconds = (u32)TmpSeconds; | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 	double ms = tp.millitm / 1000.0 / 1000.0; |     double ms = tp.millitm / 1000.0 / 1000.0; | ||||||
| #else | #else | ||||||
| 	double ms = t.tv_usec / 1000000.0; |     double ms = t.tv_usec / 1000000.0; | ||||||
| #endif | #endif | ||||||
| 	double TmpTime = Seconds + ms; |     double TmpTime = Seconds + ms; | ||||||
| 
 | 
 | ||||||
| 	return TmpTime; |     return TmpTime; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // Namespace Common
 | } // Namespace Common
 | ||||||
|  |  | ||||||
|  | @ -13,32 +13,32 @@ namespace Common | ||||||
| class Timer | class Timer | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	Timer(); |     Timer(); | ||||||
| 
 | 
 | ||||||
| 	void Start(); |     void Start(); | ||||||
| 	void Stop(); |     void Stop(); | ||||||
| 	void Update(); |     void Update(); | ||||||
| 
 | 
 | ||||||
| 	// The time difference is always returned in milliseconds, regardless of alternative internal representation
 |     // The time difference is always returned in milliseconds, regardless of alternative internal representation
 | ||||||
| 	u64 GetTimeDifference(); |     u64 GetTimeDifference(); | ||||||
| 	void AddTimeDifference(); |     void AddTimeDifference(); | ||||||
| 
 | 
 | ||||||
| 	static void IncreaseResolution(); |     static void IncreaseResolution(); | ||||||
| 	static void RestoreResolution(); |     static void RestoreResolution(); | ||||||
| 	static u64 GetTimeSinceJan1970(); |     static u64 GetTimeSinceJan1970(); | ||||||
| 	static u64 GetLocalTimeSinceJan1970(); |     static u64 GetLocalTimeSinceJan1970(); | ||||||
| 	static double GetDoubleTime(); |     static double GetDoubleTime(); | ||||||
| 
 | 
 | ||||||
| 	static std::string GetTimeFormatted(); |     static std::string GetTimeFormatted(); | ||||||
| 	std::string GetTimeElapsedFormatted() const; |     std::string GetTimeElapsedFormatted() const; | ||||||
| 	u64 GetTimeElapsed(); |     u64 GetTimeElapsed(); | ||||||
| 
 | 
 | ||||||
| 	static u32 GetTimeMs(); |     static u32 GetTimeMs(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	u64 m_LastTime; |     u64 m_LastTime; | ||||||
| 	u64 m_StartTime; |     u64 m_StartTime; | ||||||
| 	bool m_Running; |     bool m_Running; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // Namespace Common
 | } // Namespace Common
 | ||||||
|  |  | ||||||
|  | @ -31,7 +31,7 @@ | ||||||
| 
 | 
 | ||||||
| // is start of UTF sequence
 | // is start of UTF sequence
 | ||||||
| inline bool isutf(char c) { | inline bool isutf(char c) { | ||||||
| 	return (c & 0xC0) != 0x80; |     return (c & 0xC0) != 0x80; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const u32 offsetsFromUTF8[6] = { | 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, | ||||||
|   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, |   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 */ | /* returns length of next utf-8 sequence */ | ||||||
|  | @ -405,59 +405,59 @@ int u8_is_locale_utf8(const char *locale) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int UTF8StringNonASCIICount(const char *utf8string) { | int UTF8StringNonASCIICount(const char *utf8string) { | ||||||
| 	UTF8 utf(utf8string); |     UTF8 utf(utf8string); | ||||||
| 	int count = 0; |     int count = 0; | ||||||
| 	while (!utf.end()) { |     while (!utf.end()) { | ||||||
| 		int c = utf.next(); |         int c = utf.next(); | ||||||
| 		if (c > 127) |         if (c > 127) | ||||||
| 			++count; |             ++count; | ||||||
| 	} |     } | ||||||
| 	return count; |     return count; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool UTF8StringHasNonASCII(const char *utf8string) { | bool UTF8StringHasNonASCII(const char *utf8string) { | ||||||
| 	return UTF8StringNonASCIICount(utf8string) > 0; |     return UTF8StringNonASCIICount(utf8string) > 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 
 | 
 | ||||||
| std::string ConvertWStringToUTF8(const wchar_t *wstr) { | std::string ConvertWStringToUTF8(const wchar_t *wstr) { | ||||||
| 	int len = (int)wcslen(wstr); |     int len = (int)wcslen(wstr); | ||||||
| 	int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, NULL, NULL); |     int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, NULL, NULL); | ||||||
| 	std::string s; |     std::string s; | ||||||
| 	s.resize(size); |     s.resize(size); | ||||||
| 	if (size > 0) { |     if (size > 0) { | ||||||
| 		WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, NULL, NULL); |         WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, NULL, NULL); | ||||||
| 	} |     } | ||||||
| 	return s; |     return s; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string ConvertWStringToUTF8(const std::wstring &wstr) { | std::string ConvertWStringToUTF8(const std::wstring &wstr) { | ||||||
| 	int len = (int)wstr.size(); |     int len = (int)wstr.size(); | ||||||
| 	int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL); |     int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL); | ||||||
| 	std::string s; |     std::string s; | ||||||
| 	s.resize(size); |     s.resize(size); | ||||||
| 	if (size > 0) { |     if (size > 0) { | ||||||
| 		WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, NULL, NULL); |         WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, NULL, NULL); | ||||||
| 	} |     } | ||||||
| 	return s; |     return s; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { | void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { | ||||||
| 	int len = (int)source.size(); |     int len = (int)source.size(); | ||||||
| 	int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); |     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)); |     MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::wstring ConvertUTF8ToWString(const std::string &source) { | std::wstring ConvertUTF8ToWString(const std::string &source) { | ||||||
| 	int len = (int)source.size(); |     int len = (int)source.size(); | ||||||
| 	int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); |     int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); | ||||||
| 	std::wstring str; |     std::wstring str; | ||||||
| 	str.resize(size); |     str.resize(size); | ||||||
| 	if (size > 0) { |     if (size > 0) { | ||||||
| 		MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, &str[0], size); |         MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, &str[0], size); | ||||||
| 	} |     } | ||||||
| 	return str; |     return str; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  | @ -25,29 +25,29 @@ int u8_strlen(const char *s); | ||||||
| 
 | 
 | ||||||
| class UTF8 { | class UTF8 { | ||||||
| public: | public: | ||||||
| 	static const u32 INVALID = (u32)-1; |     static const u32 INVALID = (u32)-1; | ||||||
| 	UTF8(const char *c) : c_(c), index_(0) {} |     UTF8(const char *c) : c_(c), index_(0) {} | ||||||
| 	bool end() const { return c_[index_] == 0; } |     bool end() const { return c_[index_] == 0; } | ||||||
| 	u32 next() { |     u32 next() { | ||||||
| 		return u8_nextchar(c_, &index_); |         return u8_nextchar(c_, &index_); | ||||||
| 	} |     } | ||||||
| 	u32 peek() { |     u32 peek() { | ||||||
| 		int tempIndex = index_; |         int tempIndex = index_; | ||||||
| 		return u8_nextchar(c_, &tempIndex); |         return u8_nextchar(c_, &tempIndex); | ||||||
| 	} |     } | ||||||
| 	int length() const { |     int length() const { | ||||||
| 		return u8_strlen(c_); |         return u8_strlen(c_); | ||||||
| 	} |     } | ||||||
| 	int byteIndex() const { |     int byteIndex() const { | ||||||
| 		return index_; |         return index_; | ||||||
| 	} |     } | ||||||
| 	static int encode(char *dest, u32 ch) { |     static int encode(char *dest, u32 ch) { | ||||||
| 		return u8_wc_toutf8(dest, ch); |         return u8_wc_toutf8(dest, ch); | ||||||
| 	} |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	const char *c_; |     const char *c_; | ||||||
| 	int index_; |     int index_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| int UTF8StringNonASCIICount(const char *utf8string); | int UTF8StringNonASCIICount(const char *utf8string); | ||||||
|  |  | ||||||
|  | @ -6,22 +6,22 @@ | ||||||
| #include "scm_rev.h" | #include "scm_rev.h" | ||||||
| 
 | 
 | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
| 	#define BUILD_TYPE_STR "Debug " |     #define BUILD_TYPE_STR "Debug " | ||||||
| #elif defined DEBUGFAST | #elif defined DEBUGFAST | ||||||
| 	#define BUILD_TYPE_STR "DebugFast " |     #define BUILD_TYPE_STR "DebugFast " | ||||||
| #else | #else | ||||||
| 	#define BUILD_TYPE_STR "" |     #define BUILD_TYPE_STR "" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| const char *scm_rev_str = "emu " | const char *scm_rev_str = "emu " | ||||||
| #if !SCM_IS_MASTER | #if !SCM_IS_MASTER | ||||||
| 	"[" SCM_BRANCH_STR "] " |     "[" SCM_BRANCH_STR "] " | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef __INTEL_COMPILER | #ifdef __INTEL_COMPILER | ||||||
| 	BUILD_TYPE_STR SCM_DESC_STR "-ICC"; |     BUILD_TYPE_STR SCM_DESC_STR "-ICC"; | ||||||
| #else | #else | ||||||
| 	BUILD_TYPE_STR SCM_DESC_STR; |     BUILD_TYPE_STR SCM_DESC_STR; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef _M_X64 | #ifdef _M_X64 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue