convert tabs to spaces
This commit is contained in:
		@@ -1,18 +1,18 @@
 | 
			
		||||
set(SRCS	src/break_points.cpp
 | 
			
		||||
			src/console_listener.cpp
 | 
			
		||||
			src/extended_trace.cpp
 | 
			
		||||
			src/file_search.cpp
 | 
			
		||||
			src/file_util.cpp
 | 
			
		||||
			src/hash.cpp
 | 
			
		||||
			src/log_manager.cpp
 | 
			
		||||
			src/math_util.cpp
 | 
			
		||||
			src/mem_arena.cpp
 | 
			
		||||
			src/memory_util.cpp
 | 
			
		||||
			src/misc.cpp
 | 
			
		||||
			src/msg_handler.cpp
 | 
			
		||||
			src/string_util.cpp
 | 
			
		||||
			src/thread.cpp
 | 
			
		||||
			src/timer.cpp
 | 
			
		||||
			src/version.cpp)
 | 
			
		||||
set(SRCS    src/break_points.cpp
 | 
			
		||||
            src/console_listener.cpp
 | 
			
		||||
            src/extended_trace.cpp
 | 
			
		||||
            src/file_search.cpp
 | 
			
		||||
            src/file_util.cpp
 | 
			
		||||
            src/hash.cpp
 | 
			
		||||
            src/log_manager.cpp
 | 
			
		||||
            src/math_util.cpp
 | 
			
		||||
            src/mem_arena.cpp
 | 
			
		||||
            src/memory_util.cpp
 | 
			
		||||
            src/misc.cpp
 | 
			
		||||
            src/msg_handler.cpp
 | 
			
		||||
            src/string_util.cpp
 | 
			
		||||
            src/thread.cpp
 | 
			
		||||
            src/timer.cpp
 | 
			
		||||
            src/version.cpp)
 | 
			
		||||
 | 
			
		||||
add_library(common STATIC ${SRCS})
 | 
			
		||||
 
 | 
			
		||||
@@ -25,42 +25,42 @@ namespace Common
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void AtomicAdd(volatile u32& target, u32 value) {
 | 
			
		||||
	__sync_add_and_fetch(&target, value);
 | 
			
		||||
    __sync_add_and_fetch(&target, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicAnd(volatile u32& target, u32 value) {
 | 
			
		||||
	__sync_and_and_fetch(&target, value);
 | 
			
		||||
    __sync_and_and_fetch(&target, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicDecrement(volatile u32& target) {
 | 
			
		||||
	__sync_add_and_fetch(&target, -1);
 | 
			
		||||
    __sync_add_and_fetch(&target, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicIncrement(volatile u32& target) {
 | 
			
		||||
	__sync_add_and_fetch(&target, 1);
 | 
			
		||||
    __sync_add_and_fetch(&target, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline u32 AtomicLoad(volatile u32& src) {
 | 
			
		||||
	return src; // 32-bit reads are always atomic.
 | 
			
		||||
    return src; // 32-bit reads are always atomic.
 | 
			
		||||
}
 | 
			
		||||
inline u32 AtomicLoadAcquire(volatile u32& src) {
 | 
			
		||||
	//keep the compiler from caching any memory references
 | 
			
		||||
	u32 result = src; // 32-bit reads are always atomic.
 | 
			
		||||
	//__sync_synchronize(); // TODO: May not be necessary.
 | 
			
		||||
	// Compiler instruction only. x86 loads always have acquire semantics.
 | 
			
		||||
	__asm__ __volatile__ ( "":::"memory" );
 | 
			
		||||
	return result;
 | 
			
		||||
    //keep the compiler from caching any memory references
 | 
			
		||||
    u32 result = src; // 32-bit reads are always atomic.
 | 
			
		||||
    //__sync_synchronize(); // TODO: May not be necessary.
 | 
			
		||||
    // Compiler instruction only. x86 loads always have acquire semantics.
 | 
			
		||||
    __asm__ __volatile__ ( "":::"memory" );
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicOr(volatile u32& target, u32 value) {
 | 
			
		||||
	__sync_or_and_fetch(&target, value);
 | 
			
		||||
    __sync_or_and_fetch(&target, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicStore(volatile u32& dest, u32 value) {
 | 
			
		||||
	dest = value; // 32-bit writes are always atomic.
 | 
			
		||||
    dest = value; // 32-bit writes are always atomic.
 | 
			
		||||
}
 | 
			
		||||
inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
 | 
			
		||||
	__sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics.
 | 
			
		||||
    __sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -31,40 +31,40 @@ namespace Common
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void AtomicAdd(volatile u32& target, u32 value) {
 | 
			
		||||
	InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value);
 | 
			
		||||
    InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicAnd(volatile u32& target, u32 value) {
 | 
			
		||||
	_InterlockedAnd((volatile LONG*)&target, (LONG)value);
 | 
			
		||||
    _InterlockedAnd((volatile LONG*)&target, (LONG)value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicIncrement(volatile u32& target) {
 | 
			
		||||
	InterlockedIncrement((volatile LONG*)&target);
 | 
			
		||||
    InterlockedIncrement((volatile LONG*)&target);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicDecrement(volatile u32& target) {
 | 
			
		||||
	InterlockedDecrement((volatile LONG*)&target);
 | 
			
		||||
    InterlockedDecrement((volatile LONG*)&target);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline u32 AtomicLoad(volatile u32& src) {
 | 
			
		||||
	return src; // 32-bit reads are always atomic.
 | 
			
		||||
    return src; // 32-bit reads are always atomic.
 | 
			
		||||
}
 | 
			
		||||
inline u32 AtomicLoadAcquire(volatile u32& src) {
 | 
			
		||||
	u32 result = src; // 32-bit reads are always atomic.
 | 
			
		||||
	_ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics.
 | 
			
		||||
	return result;
 | 
			
		||||
    u32 result = src; // 32-bit reads are always atomic.
 | 
			
		||||
    _ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics.
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicOr(volatile u32& target, u32 value) {
 | 
			
		||||
	_InterlockedOr((volatile LONG*)&target, (LONG)value);
 | 
			
		||||
    _InterlockedOr((volatile LONG*)&target, (LONG)value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void AtomicStore(volatile u32& dest, u32 value) {
 | 
			
		||||
	dest = value; // 32-bit writes are always atomic.
 | 
			
		||||
    dest = value; // 32-bit writes are always atomic.
 | 
			
		||||
}
 | 
			
		||||
inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
 | 
			
		||||
	_WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics.
 | 
			
		||||
	dest = value; // 32-bit writes are always atomic.
 | 
			
		||||
    _WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics.
 | 
			
		||||
    dest = value; // 32-bit writes are always atomic.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,193 +11,193 @@
 | 
			
		||||
 | 
			
		||||
bool BreakPoints::IsAddressBreakPoint(u32 _iAddress)
 | 
			
		||||
{
 | 
			
		||||
	for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i)
 | 
			
		||||
		if (i->iAddress == _iAddress)
 | 
			
		||||
			return true;
 | 
			
		||||
	return false;
 | 
			
		||||
    for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i)
 | 
			
		||||
        if (i->iAddress == _iAddress)
 | 
			
		||||
            return true;
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BreakPoints::IsTempBreakPoint(u32 _iAddress)
 | 
			
		||||
{
 | 
			
		||||
	for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i)
 | 
			
		||||
		if (i->iAddress == _iAddress && i->bTemporary)
 | 
			
		||||
			return true;
 | 
			
		||||
	return false;
 | 
			
		||||
    for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i)
 | 
			
		||||
        if (i->iAddress == _iAddress && i->bTemporary)
 | 
			
		||||
            return true;
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const
 | 
			
		||||
{
 | 
			
		||||
	TBreakPointsStr bps;
 | 
			
		||||
	for (TBreakPoints::const_iterator i = m_BreakPoints.begin();
 | 
			
		||||
		i != m_BreakPoints.end(); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		if (!i->bTemporary)
 | 
			
		||||
		{
 | 
			
		||||
			std::stringstream bp;
 | 
			
		||||
			bp << std::hex << i->iAddress << " " << (i->bOn ? "n" : "");
 | 
			
		||||
			bps.push_back(bp.str());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    TBreakPointsStr bps;
 | 
			
		||||
    for (TBreakPoints::const_iterator i = m_BreakPoints.begin();
 | 
			
		||||
        i != m_BreakPoints.end(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        if (!i->bTemporary)
 | 
			
		||||
        {
 | 
			
		||||
            std::stringstream bp;
 | 
			
		||||
            bp << std::hex << i->iAddress << " " << (i->bOn ? "n" : "");
 | 
			
		||||
            bps.push_back(bp.str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	return bps;
 | 
			
		||||
    return bps;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BreakPoints::AddFromStrings(const TBreakPointsStr& bps)
 | 
			
		||||
{
 | 
			
		||||
	for (TBreakPointsStr::const_iterator i = bps.begin(); i != bps.end(); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		TBreakPoint bp;
 | 
			
		||||
		std::stringstream bpstr;
 | 
			
		||||
		bpstr << std::hex << *i;
 | 
			
		||||
		bpstr >> bp.iAddress;
 | 
			
		||||
		bp.bOn = i->find("n") != i->npos;
 | 
			
		||||
		bp.bTemporary = false;
 | 
			
		||||
		Add(bp);
 | 
			
		||||
	}
 | 
			
		||||
    for (TBreakPointsStr::const_iterator i = bps.begin(); i != bps.end(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        TBreakPoint bp;
 | 
			
		||||
        std::stringstream bpstr;
 | 
			
		||||
        bpstr << std::hex << *i;
 | 
			
		||||
        bpstr >> bp.iAddress;
 | 
			
		||||
        bp.bOn = i->find("n") != i->npos;
 | 
			
		||||
        bp.bTemporary = false;
 | 
			
		||||
        Add(bp);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BreakPoints::Add(const TBreakPoint& bp)
 | 
			
		||||
{
 | 
			
		||||
	if (!IsAddressBreakPoint(bp.iAddress))
 | 
			
		||||
	{
 | 
			
		||||
		m_BreakPoints.push_back(bp);
 | 
			
		||||
		//if (jit)
 | 
			
		||||
		//	jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 | 
			
		||||
	}
 | 
			
		||||
    if (!IsAddressBreakPoint(bp.iAddress))
 | 
			
		||||
    {
 | 
			
		||||
        m_BreakPoints.push_back(bp);
 | 
			
		||||
        //if (jit)
 | 
			
		||||
        //    jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BreakPoints::Add(u32 em_address, bool temp)
 | 
			
		||||
{
 | 
			
		||||
	if (!IsAddressBreakPoint(em_address)) // only add new addresses
 | 
			
		||||
	{
 | 
			
		||||
		TBreakPoint pt; // breakpoint settings
 | 
			
		||||
		pt.bOn = true;
 | 
			
		||||
		pt.bTemporary = temp;
 | 
			
		||||
		pt.iAddress = em_address;
 | 
			
		||||
    if (!IsAddressBreakPoint(em_address)) // only add new addresses
 | 
			
		||||
    {
 | 
			
		||||
        TBreakPoint pt; // breakpoint settings
 | 
			
		||||
        pt.bOn = true;
 | 
			
		||||
        pt.bTemporary = temp;
 | 
			
		||||
        pt.iAddress = em_address;
 | 
			
		||||
 | 
			
		||||
		m_BreakPoints.push_back(pt);
 | 
			
		||||
        m_BreakPoints.push_back(pt);
 | 
			
		||||
 | 
			
		||||
		//if (jit)
 | 
			
		||||
		//	jit->GetBlockCache()->InvalidateICache(em_address, 4);
 | 
			
		||||
	}
 | 
			
		||||
        //if (jit)
 | 
			
		||||
        //    jit->GetBlockCache()->InvalidateICache(em_address, 4);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BreakPoints::Remove(u32 em_address)
 | 
			
		||||
{
 | 
			
		||||
	for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		if (i->iAddress == em_address)
 | 
			
		||||
		{
 | 
			
		||||
			m_BreakPoints.erase(i);
 | 
			
		||||
			//if (jit)
 | 
			
		||||
			//	jit->GetBlockCache()->InvalidateICache(em_address, 4);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        if (i->iAddress == em_address)
 | 
			
		||||
        {
 | 
			
		||||
            m_BreakPoints.erase(i);
 | 
			
		||||
            //if (jit)
 | 
			
		||||
            //    jit->GetBlockCache()->InvalidateICache(em_address, 4);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BreakPoints::Clear()
 | 
			
		||||
{
 | 
			
		||||
	//if (jit)
 | 
			
		||||
	//{
 | 
			
		||||
	//	std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(),
 | 
			
		||||
	//		[](const TBreakPoint& bp)
 | 
			
		||||
	//		{
 | 
			
		||||
	//			jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 | 
			
		||||
	//		}
 | 
			
		||||
	//	);
 | 
			
		||||
	//}
 | 
			
		||||
	
 | 
			
		||||
	m_BreakPoints.clear();
 | 
			
		||||
    //if (jit)
 | 
			
		||||
    //{
 | 
			
		||||
    //    std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(),
 | 
			
		||||
    //        [](const TBreakPoint& bp)
 | 
			
		||||
    //        {
 | 
			
		||||
    //            jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
 | 
			
		||||
    //        }
 | 
			
		||||
    //    );
 | 
			
		||||
    //}
 | 
			
		||||
    
 | 
			
		||||
    m_BreakPoints.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MemChecks::TMemChecksStr MemChecks::GetStrings() const
 | 
			
		||||
{
 | 
			
		||||
	TMemChecksStr mcs;
 | 
			
		||||
	for (TMemChecks::const_iterator i = m_MemChecks.begin();
 | 
			
		||||
		i != m_MemChecks.end(); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		std::stringstream mc;
 | 
			
		||||
		mc << std::hex << i->StartAddress;
 | 
			
		||||
		mc << " " << (i->bRange ? i->EndAddress : i->StartAddress) << " " <<
 | 
			
		||||
			(i->bRange ? "n" : "") << (i->OnRead ? "r" : "") <<
 | 
			
		||||
			(i->OnWrite ? "w" : "") << (i->Log ? "l" : "") << (i->Break ? "p" : "");
 | 
			
		||||
		mcs.push_back(mc.str());
 | 
			
		||||
	}
 | 
			
		||||
    TMemChecksStr mcs;
 | 
			
		||||
    for (TMemChecks::const_iterator i = m_MemChecks.begin();
 | 
			
		||||
        i != m_MemChecks.end(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        std::stringstream mc;
 | 
			
		||||
        mc << std::hex << i->StartAddress;
 | 
			
		||||
        mc << " " << (i->bRange ? i->EndAddress : i->StartAddress) << " " <<
 | 
			
		||||
            (i->bRange ? "n" : "") << (i->OnRead ? "r" : "") <<
 | 
			
		||||
            (i->OnWrite ? "w" : "") << (i->Log ? "l" : "") << (i->Break ? "p" : "");
 | 
			
		||||
        mcs.push_back(mc.str());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	return mcs;
 | 
			
		||||
    return mcs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MemChecks::AddFromStrings(const TMemChecksStr& mcs)
 | 
			
		||||
{
 | 
			
		||||
	for (TMemChecksStr::const_iterator i = mcs.begin(); i != mcs.end(); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		TMemCheck mc;
 | 
			
		||||
		std::stringstream mcstr;
 | 
			
		||||
		mcstr << std::hex << *i;
 | 
			
		||||
		mcstr >> mc.StartAddress;
 | 
			
		||||
		mc.bRange	= i->find("n") != i->npos;
 | 
			
		||||
		mc.OnRead	= i->find("r") != i->npos;
 | 
			
		||||
		mc.OnWrite	= i->find("w") != i->npos;
 | 
			
		||||
		mc.Log		= i->find("l") != i->npos;
 | 
			
		||||
		mc.Break	= i->find("p") != i->npos;
 | 
			
		||||
		if (mc.bRange)
 | 
			
		||||
			mcstr >> mc.EndAddress;
 | 
			
		||||
		else
 | 
			
		||||
			mc.EndAddress = mc.StartAddress;
 | 
			
		||||
		Add(mc);
 | 
			
		||||
	}
 | 
			
		||||
    for (TMemChecksStr::const_iterator i = mcs.begin(); i != mcs.end(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        TMemCheck mc;
 | 
			
		||||
        std::stringstream mcstr;
 | 
			
		||||
        mcstr << std::hex << *i;
 | 
			
		||||
        mcstr >> mc.StartAddress;
 | 
			
		||||
        mc.bRange    = i->find("n") != i->npos;
 | 
			
		||||
        mc.OnRead    = i->find("r") != i->npos;
 | 
			
		||||
        mc.OnWrite    = i->find("w") != i->npos;
 | 
			
		||||
        mc.Log        = i->find("l") != i->npos;
 | 
			
		||||
        mc.Break    = i->find("p") != i->npos;
 | 
			
		||||
        if (mc.bRange)
 | 
			
		||||
            mcstr >> mc.EndAddress;
 | 
			
		||||
        else
 | 
			
		||||
            mc.EndAddress = mc.StartAddress;
 | 
			
		||||
        Add(mc);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MemChecks::Add(const TMemCheck& _rMemoryCheck)
 | 
			
		||||
{
 | 
			
		||||
	if (GetMemCheck(_rMemoryCheck.StartAddress) == 0)
 | 
			
		||||
		m_MemChecks.push_back(_rMemoryCheck);
 | 
			
		||||
    if (GetMemCheck(_rMemoryCheck.StartAddress) == 0)
 | 
			
		||||
        m_MemChecks.push_back(_rMemoryCheck);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MemChecks::Remove(u32 _Address)
 | 
			
		||||
{
 | 
			
		||||
	for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		if (i->StartAddress == _Address)
 | 
			
		||||
		{
 | 
			
		||||
			m_MemChecks.erase(i);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        if (i->StartAddress == _Address)
 | 
			
		||||
        {
 | 
			
		||||
            m_MemChecks.erase(i);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TMemCheck *MemChecks::GetMemCheck(u32 address)
 | 
			
		||||
{
 | 
			
		||||
	for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		if (i->bRange)
 | 
			
		||||
		{
 | 
			
		||||
			if (address >= i->StartAddress && address <= i->EndAddress)
 | 
			
		||||
				return &(*i);
 | 
			
		||||
		}
 | 
			
		||||
		else if (i->StartAddress == address)
 | 
			
		||||
			return &(*i);
 | 
			
		||||
	}
 | 
			
		||||
    for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        if (i->bRange)
 | 
			
		||||
        {
 | 
			
		||||
            if (address >= i->StartAddress && address <= i->EndAddress)
 | 
			
		||||
                return &(*i);
 | 
			
		||||
        }
 | 
			
		||||
        else if (i->StartAddress == address)
 | 
			
		||||
            return &(*i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// none found
 | 
			
		||||
	return 0;
 | 
			
		||||
    // none found
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TMemCheck::Action(DebugInterface *debug_interface, u32 iValue, u32 addr,
 | 
			
		||||
						bool write, int size, u32 pc)
 | 
			
		||||
                        bool write, int size, u32 pc)
 | 
			
		||||
{
 | 
			
		||||
	if ((write && OnWrite) || (!write && OnRead))
 | 
			
		||||
	{
 | 
			
		||||
		if (Log)
 | 
			
		||||
		{
 | 
			
		||||
			INFO_LOG(MEMMAP, "CHK %08x (%s) %s%i %0*x at %08x (%s)",
 | 
			
		||||
				pc, debug_interface->getDescription(pc).c_str(),
 | 
			
		||||
				write ? "Write" : "Read", size*8, size*2, iValue, addr,
 | 
			
		||||
				debug_interface->getDescription(addr).c_str()
 | 
			
		||||
				);
 | 
			
		||||
		}
 | 
			
		||||
		if (Break)
 | 
			
		||||
			debug_interface->breakNow();
 | 
			
		||||
	}
 | 
			
		||||
    if ((write && OnWrite) || (!write && OnRead))
 | 
			
		||||
    {
 | 
			
		||||
        if (Log)
 | 
			
		||||
        {
 | 
			
		||||
            INFO_LOG(MEMMAP, "CHK %08x (%s) %s%i %0*x at %08x (%s)",
 | 
			
		||||
                pc, debug_interface->getDescription(pc).c_str(),
 | 
			
		||||
                write ? "Write" : "Read", size*8, size*2, iValue, addr,
 | 
			
		||||
                debug_interface->getDescription(addr).c_str()
 | 
			
		||||
                );
 | 
			
		||||
        }
 | 
			
		||||
        if (Break)
 | 
			
		||||
            debug_interface->breakNow();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,64 +14,64 @@ class DebugInterface;
 | 
			
		||||
 | 
			
		||||
struct TBreakPoint
 | 
			
		||||
{
 | 
			
		||||
	u32		iAddress;
 | 
			
		||||
	bool	bOn;
 | 
			
		||||
	bool	bTemporary;
 | 
			
		||||
    u32        iAddress;
 | 
			
		||||
    bool    bOn;
 | 
			
		||||
    bool    bTemporary;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct TMemCheck
 | 
			
		||||
{
 | 
			
		||||
	TMemCheck() {
 | 
			
		||||
		numHits = 0;
 | 
			
		||||
		StartAddress = EndAddress = 0;
 | 
			
		||||
		bRange = OnRead = OnWrite = Log = Break = false;
 | 
			
		||||
	}
 | 
			
		||||
	u32 StartAddress;
 | 
			
		||||
	u32 EndAddress;
 | 
			
		||||
    TMemCheck() {
 | 
			
		||||
        numHits = 0;
 | 
			
		||||
        StartAddress = EndAddress = 0;
 | 
			
		||||
        bRange = OnRead = OnWrite = Log = Break = false;
 | 
			
		||||
    }
 | 
			
		||||
    u32 StartAddress;
 | 
			
		||||
    u32 EndAddress;
 | 
			
		||||
 | 
			
		||||
	bool	bRange;
 | 
			
		||||
    bool    bRange;
 | 
			
		||||
 | 
			
		||||
	bool	OnRead;
 | 
			
		||||
	bool	OnWrite;
 | 
			
		||||
    bool    OnRead;
 | 
			
		||||
    bool    OnWrite;
 | 
			
		||||
 | 
			
		||||
	bool	Log;
 | 
			
		||||
	bool	Break;
 | 
			
		||||
    bool    Log;
 | 
			
		||||
    bool    Break;
 | 
			
		||||
 | 
			
		||||
	u32		numHits;
 | 
			
		||||
    u32        numHits;
 | 
			
		||||
 | 
			
		||||
	void Action(DebugInterface *dbg_interface, u32 _iValue, u32 addr,
 | 
			
		||||
				bool write, int size, u32 pc);
 | 
			
		||||
    void Action(DebugInterface *dbg_interface, u32 _iValue, u32 addr,
 | 
			
		||||
                bool write, int size, u32 pc);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Code breakpoints.
 | 
			
		||||
class BreakPoints
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	typedef std::vector<TBreakPoint> TBreakPoints;
 | 
			
		||||
	typedef std::vector<std::string> TBreakPointsStr;
 | 
			
		||||
    typedef std::vector<TBreakPoint> TBreakPoints;
 | 
			
		||||
    typedef std::vector<std::string> TBreakPointsStr;
 | 
			
		||||
 | 
			
		||||
	const TBreakPoints& GetBreakPoints() { return m_BreakPoints; }
 | 
			
		||||
    const TBreakPoints& GetBreakPoints() { return m_BreakPoints; }
 | 
			
		||||
 | 
			
		||||
	TBreakPointsStr GetStrings() const;
 | 
			
		||||
	void AddFromStrings(const TBreakPointsStr& bps);
 | 
			
		||||
    TBreakPointsStr GetStrings() const;
 | 
			
		||||
    void AddFromStrings(const TBreakPointsStr& bps);
 | 
			
		||||
 | 
			
		||||
	// is address breakpoint
 | 
			
		||||
	bool IsAddressBreakPoint(u32 _iAddress);
 | 
			
		||||
	bool IsTempBreakPoint(u32 _iAddress);
 | 
			
		||||
    // is address breakpoint
 | 
			
		||||
    bool IsAddressBreakPoint(u32 _iAddress);
 | 
			
		||||
    bool IsTempBreakPoint(u32 _iAddress);
 | 
			
		||||
 | 
			
		||||
	// Add BreakPoint
 | 
			
		||||
	void Add(u32 em_address, bool temp=false);
 | 
			
		||||
	void Add(const TBreakPoint& bp);
 | 
			
		||||
    // Add BreakPoint
 | 
			
		||||
    void Add(u32 em_address, bool temp=false);
 | 
			
		||||
    void Add(const TBreakPoint& bp);
 | 
			
		||||
 | 
			
		||||
	// Remove Breakpoint
 | 
			
		||||
	void Remove(u32 _iAddress);
 | 
			
		||||
	void Clear();
 | 
			
		||||
    // Remove Breakpoint
 | 
			
		||||
    void Remove(u32 _iAddress);
 | 
			
		||||
    void Clear();
 | 
			
		||||
 | 
			
		||||
    void DeleteByAddress(u32 _Address);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	TBreakPoints m_BreakPoints;
 | 
			
		||||
	u32	m_iBreakOnCount;
 | 
			
		||||
    TBreakPoints m_BreakPoints;
 | 
			
		||||
    u32    m_iBreakOnCount;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -79,23 +79,23 @@ private:
 | 
			
		||||
class MemChecks
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	typedef std::vector<TMemCheck> TMemChecks;
 | 
			
		||||
	typedef std::vector<std::string> TMemChecksStr;
 | 
			
		||||
    typedef std::vector<TMemCheck> TMemChecks;
 | 
			
		||||
    typedef std::vector<std::string> TMemChecksStr;
 | 
			
		||||
 | 
			
		||||
	TMemChecks m_MemChecks;
 | 
			
		||||
    TMemChecks m_MemChecks;
 | 
			
		||||
 | 
			
		||||
	const TMemChecks& GetMemChecks() { return m_MemChecks; }
 | 
			
		||||
    const TMemChecks& GetMemChecks() { return m_MemChecks; }
 | 
			
		||||
 | 
			
		||||
	TMemChecksStr GetStrings() const;
 | 
			
		||||
	void AddFromStrings(const TMemChecksStr& mcs);
 | 
			
		||||
    TMemChecksStr GetStrings() const;
 | 
			
		||||
    void AddFromStrings(const TMemChecksStr& mcs);
 | 
			
		||||
 | 
			
		||||
	void Add(const TMemCheck& _rMemoryCheck);
 | 
			
		||||
    void Add(const TMemCheck& _rMemoryCheck);
 | 
			
		||||
 | 
			
		||||
	// memory breakpoint
 | 
			
		||||
	TMemCheck *GetMemCheck(u32 address);
 | 
			
		||||
    // memory breakpoint
 | 
			
		||||
    TMemCheck *GetMemCheck(u32 address);
 | 
			
		||||
    void Remove(u32 _Address);
 | 
			
		||||
 | 
			
		||||
	void Clear() { m_MemChecks.clear(); };
 | 
			
		||||
    void Clear() { m_MemChecks.clear(); };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -34,12 +34,12 @@ extern const char *netplay_dolphin_ver;
 | 
			
		||||
class NonCopyable
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
	NonCopyable() {}
 | 
			
		||||
	NonCopyable(const NonCopyable&&) {}
 | 
			
		||||
	void operator=(const NonCopyable&&) {}
 | 
			
		||||
    NonCopyable() {}
 | 
			
		||||
    NonCopyable(const NonCopyable&&) {}
 | 
			
		||||
    void operator=(const NonCopyable&&) {}
 | 
			
		||||
private:
 | 
			
		||||
	NonCopyable(NonCopyable&);
 | 
			
		||||
	NonCopyable& operator=(NonCopyable& other);
 | 
			
		||||
    NonCopyable(NonCopyable&);
 | 
			
		||||
    NonCopyable& operator=(NonCopyable& other);
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -61,40 +61,40 @@ private:
 | 
			
		||||
#elif defined _WIN32
 | 
			
		||||
 | 
			
		||||
// Check MSC ver
 | 
			
		||||
	#if !defined _MSC_VER || _MSC_VER <= 1000
 | 
			
		||||
		#error needs at least version 1000 of MSC
 | 
			
		||||
	#endif
 | 
			
		||||
    #if !defined _MSC_VER || _MSC_VER <= 1000
 | 
			
		||||
        #error needs at least version 1000 of MSC
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
	#define NOMINMAX
 | 
			
		||||
    #define NOMINMAX
 | 
			
		||||
 | 
			
		||||
// Memory leak checks
 | 
			
		||||
	#define CHECK_HEAP_INTEGRITY()
 | 
			
		||||
    #define CHECK_HEAP_INTEGRITY()
 | 
			
		||||
 | 
			
		||||
// Alignment
 | 
			
		||||
	#define MEMORY_ALIGNED16(x) __declspec(align(16)) x
 | 
			
		||||
	#define MEMORY_ALIGNED32(x) __declspec(align(32)) x
 | 
			
		||||
	#define MEMORY_ALIGNED64(x) __declspec(align(64)) x
 | 
			
		||||
	#define MEMORY_ALIGNED128(x) __declspec(align(128)) x
 | 
			
		||||
	#define MEMORY_ALIGNED16_DECL(x) __declspec(align(16)) x
 | 
			
		||||
	#define MEMORY_ALIGNED64_DECL(x) __declspec(align(64)) x
 | 
			
		||||
    #define MEMORY_ALIGNED16(x) __declspec(align(16)) x
 | 
			
		||||
    #define MEMORY_ALIGNED32(x) __declspec(align(32)) x
 | 
			
		||||
    #define MEMORY_ALIGNED64(x) __declspec(align(64)) x
 | 
			
		||||
    #define MEMORY_ALIGNED128(x) __declspec(align(128)) x
 | 
			
		||||
    #define MEMORY_ALIGNED16_DECL(x) __declspec(align(16)) x
 | 
			
		||||
    #define MEMORY_ALIGNED64_DECL(x) __declspec(align(64)) x
 | 
			
		||||
 | 
			
		||||
// Since they are always around on windows
 | 
			
		||||
	#define HAVE_WX 1
 | 
			
		||||
	#define HAVE_OPENAL 1
 | 
			
		||||
    #define HAVE_WX 1
 | 
			
		||||
    #define HAVE_OPENAL 1
 | 
			
		||||
 | 
			
		||||
	#define HAVE_PORTAUDIO 1
 | 
			
		||||
    #define HAVE_PORTAUDIO 1
 | 
			
		||||
 | 
			
		||||
// Debug definitions
 | 
			
		||||
	#if defined(_DEBUG)
 | 
			
		||||
		#include <crtdbg.h>
 | 
			
		||||
		#undef CHECK_HEAP_INTEGRITY
 | 
			
		||||
		#define CHECK_HEAP_INTEGRITY() {if (!_CrtCheckMemory()) PanicAlert("memory corruption detected. see log.");}
 | 
			
		||||
		// If you want to see how much a pain in the ass singletons are, for example:
 | 
			
		||||
		// {614} normal block at 0x030C5310, 188 bytes long.
 | 
			
		||||
		// Data: <Master Log      > 4D 61 73 74 65 72 20 4C 6F 67 00 00 00 00 00 00
 | 
			
		||||
		struct CrtDebugBreak { CrtDebugBreak(int spot) { _CrtSetBreakAlloc(spot); } };
 | 
			
		||||
		//CrtDebugBreak breakAt(614);
 | 
			
		||||
	#endif // end DEBUG/FAST
 | 
			
		||||
    #if defined(_DEBUG)
 | 
			
		||||
        #include <crtdbg.h>
 | 
			
		||||
        #undef CHECK_HEAP_INTEGRITY
 | 
			
		||||
        #define CHECK_HEAP_INTEGRITY() {if (!_CrtCheckMemory()) PanicAlert("memory corruption detected. see log.");}
 | 
			
		||||
        // If you want to see how much a pain in the ass singletons are, for example:
 | 
			
		||||
        // {614} normal block at 0x030C5310, 188 bytes long.
 | 
			
		||||
        // Data: <Master Log      > 4D 61 73 74 65 72 20 4C 6F 67 00 00 00 00 00 00
 | 
			
		||||
        struct CrtDebugBreak { CrtDebugBreak(int spot) { _CrtSetBreakAlloc(spot); } };
 | 
			
		||||
        //CrtDebugBreak breakAt(614);
 | 
			
		||||
    #endif // end DEBUG/FAST
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -149,18 +149,18 @@ private:
 | 
			
		||||
// Host communication.
 | 
			
		||||
enum HOST_COMM
 | 
			
		||||
{
 | 
			
		||||
	// Begin at 10 in case there is already messages with wParam = 0, 1, 2 and so on
 | 
			
		||||
	WM_USER_STOP = 10,
 | 
			
		||||
	WM_USER_CREATE,
 | 
			
		||||
	WM_USER_SETCURSOR,
 | 
			
		||||
    // Begin at 10 in case there is already messages with wParam = 0, 1, 2 and so on
 | 
			
		||||
    WM_USER_STOP = 10,
 | 
			
		||||
    WM_USER_CREATE,
 | 
			
		||||
    WM_USER_SETCURSOR,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Used for notification on emulation state
 | 
			
		||||
enum EMUSTATE_CHANGE
 | 
			
		||||
{
 | 
			
		||||
	EMUSTATE_CHANGE_PLAY = 1,
 | 
			
		||||
	EMUSTATE_CHANGE_PAUSE,
 | 
			
		||||
	EMUSTATE_CHANGE_STOP
 | 
			
		||||
    EMUSTATE_CHANGE_PLAY = 1,
 | 
			
		||||
    EMUSTATE_CHANGE_PAUSE,
 | 
			
		||||
    EMUSTATE_CHANGE_STOP
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _COMMON_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ template<> struct CompileTimeAssert<true> {};
 | 
			
		||||
#define b8(x)   ( b4(x) | ( b4(x) >> 4) )
 | 
			
		||||
#define b16(x)  ( b8(x) | ( b8(x) >> 8) )  
 | 
			
		||||
#define b32(x)  (b16(x) | (b16(x) >>16) )
 | 
			
		||||
#define ROUND_UP_POW2(x)	(b32(x - 1) + 1)
 | 
			
		||||
#define ROUND_UP_POW2(x)    (b32(x - 1) + 1)
 | 
			
		||||
 | 
			
		||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 | 
			
		||||
 | 
			
		||||
@@ -29,11 +29,11 @@ template<> struct CompileTimeAssert<true> {};
 | 
			
		||||
static __inline __m128i __attribute__((__always_inline__))
 | 
			
		||||
_mm_shuffle_epi8(__m128i a, __m128i mask)
 | 
			
		||||
{
 | 
			
		||||
	__m128i result;
 | 
			
		||||
	__asm__("pshufb %1, %0"
 | 
			
		||||
		: "=x" (result)
 | 
			
		||||
		: "xm" (mask), "0" (a));
 | 
			
		||||
	return result;
 | 
			
		||||
    __m128i result;
 | 
			
		||||
    __asm__("pshufb %1, %0"
 | 
			
		||||
        : "=x" (result)
 | 
			
		||||
        : "xm" (mask), "0" (a));
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -47,103 +47,103 @@ _mm_shuffle_epi8(__m128i a, __m128i mask)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// go to debugger mode
 | 
			
		||||
	#ifdef GEKKO
 | 
			
		||||
		#define Crash()
 | 
			
		||||
	#elif defined _M_GENERIC
 | 
			
		||||
		#define Crash() { exit(1); }
 | 
			
		||||
	#else
 | 
			
		||||
		#define Crash() {asm ("int $3");}
 | 
			
		||||
	#endif
 | 
			
		||||
	#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
 | 
			
		||||
    #ifdef GEKKO
 | 
			
		||||
        #define Crash()
 | 
			
		||||
    #elif defined _M_GENERIC
 | 
			
		||||
        #define Crash() { exit(1); }
 | 
			
		||||
    #else
 | 
			
		||||
        #define Crash() {asm ("int $3");}
 | 
			
		||||
    #endif
 | 
			
		||||
    #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
 | 
			
		||||
// GCC 4.8 defines all the rotate functions now
 | 
			
		||||
// Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit
 | 
			
		||||
#ifndef _rotl
 | 
			
		||||
inline u32 _rotl(u32 x, int shift) {
 | 
			
		||||
	shift &= 31;
 | 
			
		||||
	if (!shift) return x;
 | 
			
		||||
	return (x << shift) | (x >> (32 - shift));
 | 
			
		||||
    shift &= 31;
 | 
			
		||||
    if (!shift) return x;
 | 
			
		||||
    return (x << shift) | (x >> (32 - shift));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline u32 _rotr(u32 x, int shift) {
 | 
			
		||||
	shift &= 31;
 | 
			
		||||
	if (!shift) return x;
 | 
			
		||||
	return (x >> shift) | (x << (32 - shift));
 | 
			
		||||
    shift &= 31;
 | 
			
		||||
    if (!shift) return x;
 | 
			
		||||
    return (x >> shift) | (x << (32 - shift));
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
inline u64 _rotl64(u64 x, unsigned int shift){
 | 
			
		||||
	unsigned int n = shift % 64;
 | 
			
		||||
	return (x << n) | (x >> (64 - n));
 | 
			
		||||
    unsigned int n = shift % 64;
 | 
			
		||||
    return (x << n) | (x >> (64 - n));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline u64 _rotr64(u64 x, unsigned int shift){
 | 
			
		||||
	unsigned int n = shift % 64;
 | 
			
		||||
	return (x >> n) | (x << (64 - n));
 | 
			
		||||
    unsigned int n = shift % 64;
 | 
			
		||||
    return (x >> n) | (x << (64 - n));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else // WIN32
 | 
			
		||||
// Function Cross-Compatibility
 | 
			
		||||
	#define strcasecmp _stricmp
 | 
			
		||||
	#define strncasecmp _strnicmp
 | 
			
		||||
	#define unlink _unlink
 | 
			
		||||
	#define snprintf _snprintf
 | 
			
		||||
	#define vscprintf _vscprintf
 | 
			
		||||
	
 | 
			
		||||
    #define strcasecmp _stricmp
 | 
			
		||||
    #define strncasecmp _strnicmp
 | 
			
		||||
    #define unlink _unlink
 | 
			
		||||
    #define snprintf _snprintf
 | 
			
		||||
    #define vscprintf _vscprintf
 | 
			
		||||
    
 | 
			
		||||
// Locale Cross-Compatibility
 | 
			
		||||
	#define locale_t _locale_t
 | 
			
		||||
	#define freelocale _free_locale
 | 
			
		||||
	#define newlocale(mask, locale, base) _create_locale(mask, locale)
 | 
			
		||||
	
 | 
			
		||||
	#define LC_GLOBAL_LOCALE	((locale_t)-1)
 | 
			
		||||
	#define LC_ALL_MASK			LC_ALL
 | 
			
		||||
	#define LC_COLLATE_MASK		LC_COLLATE
 | 
			
		||||
	#define LC_CTYPE_MASK		LC_CTYPE
 | 
			
		||||
	#define LC_MONETARY_MASK	LC_MONETARY
 | 
			
		||||
	#define LC_NUMERIC_MASK		LC_NUMERIC
 | 
			
		||||
	#define LC_TIME_MASK		LC_TIME
 | 
			
		||||
	
 | 
			
		||||
	inline locale_t uselocale(locale_t new_locale)
 | 
			
		||||
	{
 | 
			
		||||
		// Retrieve the current per thread locale setting
 | 
			
		||||
		bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE);
 | 
			
		||||
    #define locale_t _locale_t
 | 
			
		||||
    #define freelocale _free_locale
 | 
			
		||||
    #define newlocale(mask, locale, base) _create_locale(mask, locale)
 | 
			
		||||
    
 | 
			
		||||
    #define LC_GLOBAL_LOCALE    ((locale_t)-1)
 | 
			
		||||
    #define LC_ALL_MASK            LC_ALL
 | 
			
		||||
    #define LC_COLLATE_MASK        LC_COLLATE
 | 
			
		||||
    #define LC_CTYPE_MASK        LC_CTYPE
 | 
			
		||||
    #define LC_MONETARY_MASK    LC_MONETARY
 | 
			
		||||
    #define LC_NUMERIC_MASK        LC_NUMERIC
 | 
			
		||||
    #define LC_TIME_MASK        LC_TIME
 | 
			
		||||
    
 | 
			
		||||
    inline locale_t uselocale(locale_t new_locale)
 | 
			
		||||
    {
 | 
			
		||||
        // Retrieve the current per thread locale setting
 | 
			
		||||
        bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE);
 | 
			
		||||
 | 
			
		||||
		// Retrieve the current thread-specific locale
 | 
			
		||||
		locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE;
 | 
			
		||||
        // Retrieve the current thread-specific locale
 | 
			
		||||
        locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE;
 | 
			
		||||
 | 
			
		||||
		if(new_locale == LC_GLOBAL_LOCALE)
 | 
			
		||||
		{
 | 
			
		||||
			// Restore the global locale
 | 
			
		||||
			_configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
 | 
			
		||||
		}
 | 
			
		||||
		else if(new_locale != NULL)
 | 
			
		||||
		{
 | 
			
		||||
			// Configure the thread to set the locale only for this thread
 | 
			
		||||
			_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
 | 
			
		||||
        if(new_locale == LC_GLOBAL_LOCALE)
 | 
			
		||||
        {
 | 
			
		||||
            // Restore the global locale
 | 
			
		||||
            _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
 | 
			
		||||
        }
 | 
			
		||||
        else if(new_locale != NULL)
 | 
			
		||||
        {
 | 
			
		||||
            // Configure the thread to set the locale only for this thread
 | 
			
		||||
            _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
 | 
			
		||||
 | 
			
		||||
			// Set all locale categories
 | 
			
		||||
			for(int i = LC_MIN; i <= LC_MAX; i++)
 | 
			
		||||
				setlocale(i, new_locale->locinfo->lc_category[i].locale);
 | 
			
		||||
		}
 | 
			
		||||
            // Set all locale categories
 | 
			
		||||
            for(int i = LC_MIN; i <= LC_MAX; i++)
 | 
			
		||||
                setlocale(i, new_locale->locinfo->lc_category[i].locale);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		return old_locale;
 | 
			
		||||
	}
 | 
			
		||||
        return old_locale;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// 64 bit offsets for windows
 | 
			
		||||
	#define fseeko _fseeki64
 | 
			
		||||
	#define ftello _ftelli64
 | 
			
		||||
	#define atoll _atoi64
 | 
			
		||||
	#define stat64 _stat64
 | 
			
		||||
	#define fstat64 _fstat64
 | 
			
		||||
	#define fileno _fileno
 | 
			
		||||
    #define fseeko _fseeki64
 | 
			
		||||
    #define ftello _ftelli64
 | 
			
		||||
    #define atoll _atoi64
 | 
			
		||||
    #define stat64 _stat64
 | 
			
		||||
    #define fstat64 _fstat64
 | 
			
		||||
    #define fileno _fileno
 | 
			
		||||
 | 
			
		||||
	#if _M_IX86
 | 
			
		||||
		#define Crash() {__asm int 3}
 | 
			
		||||
	#else
 | 
			
		||||
    #if _M_IX86
 | 
			
		||||
        #define Crash() {__asm int 3}
 | 
			
		||||
    #else
 | 
			
		||||
extern "C" {
 | 
			
		||||
	__declspec(dllimport) void __stdcall DebugBreak(void);
 | 
			
		||||
    __declspec(dllimport) void __stdcall DebugBreak(void);
 | 
			
		||||
}
 | 
			
		||||
		#define Crash() {DebugBreak();}
 | 
			
		||||
	#endif // M_IX86
 | 
			
		||||
        #define Crash() {DebugBreak();}
 | 
			
		||||
    #endif // M_IX86
 | 
			
		||||
#endif // WIN32 ndef
 | 
			
		||||
 | 
			
		||||
// Dolphin's min and max functions
 | 
			
		||||
@@ -186,11 +186,11 @@ inline u32 swap32(u32 _data) {return bswap_32(_data);}
 | 
			
		||||
inline u64 swap64(u64 _data) {return bswap_64(_data);}
 | 
			
		||||
#elif __APPLE__
 | 
			
		||||
inline __attribute__((always_inline)) u16 swap16(u16 _data)
 | 
			
		||||
	{return (_data >> 8) | (_data << 8);}
 | 
			
		||||
    {return (_data >> 8) | (_data << 8);}
 | 
			
		||||
inline __attribute__((always_inline)) u32 swap32(u32 _data)
 | 
			
		||||
	{return __builtin_bswap32(_data);}
 | 
			
		||||
    {return __builtin_bswap32(_data);}
 | 
			
		||||
inline __attribute__((always_inline)) u64 swap64(u64 _data)
 | 
			
		||||
	{return __builtin_bswap64(_data);}
 | 
			
		||||
    {return __builtin_bswap64(_data);}
 | 
			
		||||
#elif __FreeBSD__
 | 
			
		||||
inline u16 swap16(u16 _data) {return bswap16(_data);}
 | 
			
		||||
inline u32 swap32(u32 _data) {return bswap32(_data);}
 | 
			
		||||
@@ -216,28 +216,28 @@ inline void swap<1>(u8* data)
 | 
			
		||||
template <>
 | 
			
		||||
inline void swap<2>(u8* data)
 | 
			
		||||
{
 | 
			
		||||
	*reinterpret_cast<u16*>(data) = swap16(data);
 | 
			
		||||
    *reinterpret_cast<u16*>(data) = swap16(data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
inline void swap<4>(u8* data)
 | 
			
		||||
{
 | 
			
		||||
	*reinterpret_cast<u32*>(data) = swap32(data);
 | 
			
		||||
    *reinterpret_cast<u32*>(data) = swap32(data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
inline void swap<8>(u8* data)
 | 
			
		||||
{
 | 
			
		||||
	*reinterpret_cast<u64*>(data) = swap64(data);
 | 
			
		||||
    *reinterpret_cast<u64*>(data) = swap64(data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline T FromBigEndian(T data)
 | 
			
		||||
{
 | 
			
		||||
	//static_assert(std::is_arithmetic<T>::value, "function only makes sense with arithmetic types");
 | 
			
		||||
	
 | 
			
		||||
	swap<sizeof(data)>(reinterpret_cast<u8*>(&data));
 | 
			
		||||
	return data;
 | 
			
		||||
    //static_assert(std::is_arithmetic<T>::value, "function only makes sense with arithmetic types");
 | 
			
		||||
    
 | 
			
		||||
    swap<sizeof(data)>(reinterpret_cast<u8*>(&data));
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // Namespace Common
 | 
			
		||||
 
 | 
			
		||||
@@ -13,34 +13,34 @@
 | 
			
		||||
#define DIR_SEP_CHR '/'
 | 
			
		||||
 | 
			
		||||
#ifndef MAX_PATH
 | 
			
		||||
#define MAX_PATH	260
 | 
			
		||||
#define MAX_PATH    260
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// The user data dir
 | 
			
		||||
#define ROOT_DIR "."
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	#define USERDATA_DIR "user"
 | 
			
		||||
	#define EMU_DATA_DIR "emu"
 | 
			
		||||
    #define USERDATA_DIR "user"
 | 
			
		||||
    #define EMU_DATA_DIR "emu"
 | 
			
		||||
#else
 | 
			
		||||
	#define USERDATA_DIR "user"
 | 
			
		||||
	#ifdef USER_DIR
 | 
			
		||||
		#define EMU_DATA_DIR USER_DIR
 | 
			
		||||
	#else
 | 
			
		||||
		#define EMU_DATA_DIR ".emu"
 | 
			
		||||
	#endif
 | 
			
		||||
    #define USERDATA_DIR "user"
 | 
			
		||||
    #ifdef USER_DIR
 | 
			
		||||
        #define EMU_DATA_DIR USER_DIR
 | 
			
		||||
    #else
 | 
			
		||||
        #define EMU_DATA_DIR ".emu"
 | 
			
		||||
    #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Shared data dirs (Sys and shared User for linux)
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	#define SYSDATA_DIR "sys"
 | 
			
		||||
    #define SYSDATA_DIR "sys"
 | 
			
		||||
#else
 | 
			
		||||
	#ifdef DATA_DIR
 | 
			
		||||
		#define SYSDATA_DIR DATA_DIR "sys"
 | 
			
		||||
		#define SHARED_USER_DIR  DATA_DIR USERDATA_DIR DIR_SEP
 | 
			
		||||
	#else
 | 
			
		||||
		#define SYSDATA_DIR "sys"
 | 
			
		||||
		#define SHARED_USER_DIR  ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP
 | 
			
		||||
	#endif
 | 
			
		||||
    #ifdef DATA_DIR
 | 
			
		||||
        #define SYSDATA_DIR DATA_DIR "sys"
 | 
			
		||||
        #define SHARED_USER_DIR  DATA_DIR USERDATA_DIR DIR_SEP
 | 
			
		||||
    #else
 | 
			
		||||
        #define SYSDATA_DIR "sys"
 | 
			
		||||
        #define SHARED_USER_DIR  ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP
 | 
			
		||||
    #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Dirs in both User and Sys
 | 
			
		||||
@@ -49,31 +49,31 @@
 | 
			
		||||
#define JAP_DIR "JAP"
 | 
			
		||||
 | 
			
		||||
// Subdirs in the User dir returned by GetUserPath(D_USER_IDX)
 | 
			
		||||
#define CONFIG_DIR			"config"
 | 
			
		||||
#define GAMECONFIG_DIR		"game_config"
 | 
			
		||||
#define MAPS_DIR			"maps"
 | 
			
		||||
#define CACHE_DIR			"cache"
 | 
			
		||||
#define SHADERCACHE_DIR		"shader_cache"
 | 
			
		||||
#define STATESAVES_DIR		"state_saves"
 | 
			
		||||
#define SCREENSHOTS_DIR		"screenShots"
 | 
			
		||||
#define DUMP_DIR			"dump"
 | 
			
		||||
#define DUMP_TEXTURES_DIR	"textures"
 | 
			
		||||
#define DUMP_FRAMES_DIR		"frames"
 | 
			
		||||
#define DUMP_AUDIO_DIR		"audio"
 | 
			
		||||
#define LOGS_DIR			"logs"
 | 
			
		||||
#define SHADERS_DIR 		"shaders"
 | 
			
		||||
#define SYSCONF_DIR 		"sysconf"
 | 
			
		||||
#define CONFIG_DIR            "config"
 | 
			
		||||
#define GAMECONFIG_DIR        "game_config"
 | 
			
		||||
#define MAPS_DIR            "maps"
 | 
			
		||||
#define CACHE_DIR            "cache"
 | 
			
		||||
#define SHADERCACHE_DIR        "shader_cache"
 | 
			
		||||
#define STATESAVES_DIR        "state_saves"
 | 
			
		||||
#define SCREENSHOTS_DIR        "screenShots"
 | 
			
		||||
#define DUMP_DIR            "dump"
 | 
			
		||||
#define DUMP_TEXTURES_DIR    "textures"
 | 
			
		||||
#define DUMP_FRAMES_DIR        "frames"
 | 
			
		||||
#define DUMP_AUDIO_DIR        "audio"
 | 
			
		||||
#define LOGS_DIR            "logs"
 | 
			
		||||
#define SHADERS_DIR         "shaders"
 | 
			
		||||
#define SYSCONF_DIR         "sysconf"
 | 
			
		||||
 | 
			
		||||
// Filenames
 | 
			
		||||
// Files in the directory returned by GetUserPath(D_CONFIG_IDX)
 | 
			
		||||
#define EMU_CONFIG		"emu.ini"
 | 
			
		||||
#define DEBUGGER_CONFIG	"debugger.ini"
 | 
			
		||||
#define LOGGER_CONFIG	"logger.ini"
 | 
			
		||||
#define EMU_CONFIG        "emu.ini"
 | 
			
		||||
#define DEBUGGER_CONFIG    "debugger.ini"
 | 
			
		||||
#define LOGGER_CONFIG    "logger.ini"
 | 
			
		||||
 | 
			
		||||
// Files in the directory returned by GetUserPath(D_LOGS_IDX)
 | 
			
		||||
#define MAIN_LOG	"emu.log"
 | 
			
		||||
#define MAIN_LOG    "emu.log"
 | 
			
		||||
 | 
			
		||||
// Files in the directory returned by GetUserPath(D_SYSCONF_IDX)
 | 
			
		||||
#define SYSCONF	"SYSCONF"
 | 
			
		||||
#define SYSCONF    "SYSCONF"
 | 
			
		||||
 | 
			
		||||
#endif // _COMMON_PATHS_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -20,16 +20,16 @@
 | 
			
		||||
ConsoleListener::ConsoleListener()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	hConsole = NULL;
 | 
			
		||||
	bUseColor = true;
 | 
			
		||||
    hConsole = NULL;
 | 
			
		||||
    bUseColor = true;
 | 
			
		||||
#else
 | 
			
		||||
	bUseColor = isatty(fileno(stdout));
 | 
			
		||||
    bUseColor = isatty(fileno(stdout));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ConsoleListener::~ConsoleListener()
 | 
			
		||||
{
 | 
			
		||||
	Close();
 | 
			
		||||
    Close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 100, 100, "Dolphin Log Console"
 | 
			
		||||
@@ -38,31 +38,31 @@ ConsoleListener::~ConsoleListener()
 | 
			
		||||
void ConsoleListener::Open(bool Hidden, int Width, int Height, const char *Title)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	if (!GetConsoleWindow())
 | 
			
		||||
	{
 | 
			
		||||
		// Open the console window and create the window handle for GetStdHandle()
 | 
			
		||||
		AllocConsole();
 | 
			
		||||
		// Hide
 | 
			
		||||
		if (Hidden) ShowWindow(GetConsoleWindow(), SW_HIDE);
 | 
			
		||||
		// Save the window handle that AllocConsole() created
 | 
			
		||||
		hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
 | 
			
		||||
		// Set the console window title
 | 
			
		||||
		SetConsoleTitle(UTF8ToTStr(Title).c_str());
 | 
			
		||||
		// Set letter space
 | 
			
		||||
		LetterSpace(80, 4000);
 | 
			
		||||
		//MoveWindow(GetConsoleWindow(), 200,200, 800,800, true);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
 | 
			
		||||
	}
 | 
			
		||||
    if (!GetConsoleWindow())
 | 
			
		||||
    {
 | 
			
		||||
        // Open the console window and create the window handle for GetStdHandle()
 | 
			
		||||
        AllocConsole();
 | 
			
		||||
        // Hide
 | 
			
		||||
        if (Hidden) ShowWindow(GetConsoleWindow(), SW_HIDE);
 | 
			
		||||
        // Save the window handle that AllocConsole() created
 | 
			
		||||
        hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
 | 
			
		||||
        // Set the console window title
 | 
			
		||||
        SetConsoleTitle(UTF8ToTStr(Title).c_str());
 | 
			
		||||
        // Set letter space
 | 
			
		||||
        LetterSpace(80, 4000);
 | 
			
		||||
        //MoveWindow(GetConsoleWindow(), 200,200, 800,800, true);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ConsoleListener::UpdateHandle()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
 | 
			
		||||
    hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -70,267 +70,267 @@ void ConsoleListener::UpdateHandle()
 | 
			
		||||
void ConsoleListener::Close()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	if (hConsole == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	FreeConsole();
 | 
			
		||||
	hConsole = NULL;
 | 
			
		||||
    if (hConsole == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    FreeConsole();
 | 
			
		||||
    hConsole = NULL;
 | 
			
		||||
#else
 | 
			
		||||
	fflush(NULL);
 | 
			
		||||
    fflush(NULL);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ConsoleListener::IsOpen()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	return (hConsole != NULL);
 | 
			
		||||
    return (hConsole != NULL);
 | 
			
		||||
#else
 | 
			
		||||
	return true;
 | 
			
		||||
    return true;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  LetterSpace: SetConsoleScreenBufferSize and SetConsoleWindowInfo are
 | 
			
		||||
	dependent on each other, that's the reason for the additional checks.  
 | 
			
		||||
    dependent on each other, that's the reason for the additional checks.  
 | 
			
		||||
*/
 | 
			
		||||
void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	BOOL SB, SW;
 | 
			
		||||
	if (BufferFirst)
 | 
			
		||||
	{
 | 
			
		||||
		// Change screen buffer size
 | 
			
		||||
		COORD Co = {BufferWidth, BufferHeight};
 | 
			
		||||
		SB = SetConsoleScreenBufferSize(hConsole, Co);
 | 
			
		||||
		// Change the screen buffer window size
 | 
			
		||||
		SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom
 | 
			
		||||
		SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// Change the screen buffer window size
 | 
			
		||||
		SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom
 | 
			
		||||
		SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
 | 
			
		||||
		// Change screen buffer size
 | 
			
		||||
		COORD Co = {BufferWidth, BufferHeight};
 | 
			
		||||
		SB = SetConsoleScreenBufferSize(hConsole, Co);
 | 
			
		||||
	}
 | 
			
		||||
    BOOL SB, SW;
 | 
			
		||||
    if (BufferFirst)
 | 
			
		||||
    {
 | 
			
		||||
        // Change screen buffer size
 | 
			
		||||
        COORD Co = {BufferWidth, BufferHeight};
 | 
			
		||||
        SB = SetConsoleScreenBufferSize(hConsole, Co);
 | 
			
		||||
        // Change the screen buffer window size
 | 
			
		||||
        SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom
 | 
			
		||||
        SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // Change the screen buffer window size
 | 
			
		||||
        SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom
 | 
			
		||||
        SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
 | 
			
		||||
        // Change screen buffer size
 | 
			
		||||
        COORD Co = {BufferWidth, BufferHeight};
 | 
			
		||||
        SB = SetConsoleScreenBufferSize(hConsole, Co);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
void ConsoleListener::LetterSpace(int Width, int Height)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	// Get console info
 | 
			
		||||
	CONSOLE_SCREEN_BUFFER_INFO ConInfo;
 | 
			
		||||
	GetConsoleScreenBufferInfo(hConsole, &ConInfo);
 | 
			
		||||
    // Get console info
 | 
			
		||||
    CONSOLE_SCREEN_BUFFER_INFO ConInfo;
 | 
			
		||||
    GetConsoleScreenBufferInfo(hConsole, &ConInfo);
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	int OldBufferWidth = ConInfo.dwSize.X;
 | 
			
		||||
	int OldBufferHeight = ConInfo.dwSize.Y;
 | 
			
		||||
	int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left);
 | 
			
		||||
	int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top);
 | 
			
		||||
	//
 | 
			
		||||
	int NewBufferWidth = Width;
 | 
			
		||||
	int NewBufferHeight = Height;
 | 
			
		||||
	int NewScreenWidth = NewBufferWidth - 1;
 | 
			
		||||
	int NewScreenHeight = OldScreenHeight;
 | 
			
		||||
    //
 | 
			
		||||
    int OldBufferWidth = ConInfo.dwSize.X;
 | 
			
		||||
    int OldBufferHeight = ConInfo.dwSize.Y;
 | 
			
		||||
    int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left);
 | 
			
		||||
    int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top);
 | 
			
		||||
    //
 | 
			
		||||
    int NewBufferWidth = Width;
 | 
			
		||||
    int NewBufferHeight = Height;
 | 
			
		||||
    int NewScreenWidth = NewBufferWidth - 1;
 | 
			
		||||
    int NewScreenHeight = OldScreenHeight;
 | 
			
		||||
 | 
			
		||||
	// Width
 | 
			
		||||
	BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1));
 | 
			
		||||
	// Height
 | 
			
		||||
	BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1));
 | 
			
		||||
    // Width
 | 
			
		||||
    BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1));
 | 
			
		||||
    // Height
 | 
			
		||||
    BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1));
 | 
			
		||||
 | 
			
		||||
	// Resize the window too
 | 
			
		||||
	//MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true);
 | 
			
		||||
    // Resize the window too
 | 
			
		||||
    //MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
COORD ConsoleListener::GetCoordinates(int BytesRead, int BufferWidth)
 | 
			
		||||
{
 | 
			
		||||
	COORD Ret = {0, 0};
 | 
			
		||||
	// Full rows
 | 
			
		||||
	int Step = (int)floor((float)BytesRead / (float)BufferWidth);
 | 
			
		||||
	Ret.Y += Step;
 | 
			
		||||
	// Partial row
 | 
			
		||||
	Ret.X = BytesRead - (BufferWidth * Step);
 | 
			
		||||
	return Ret;
 | 
			
		||||
    COORD Ret = {0, 0};
 | 
			
		||||
    // Full rows
 | 
			
		||||
    int Step = (int)floor((float)BytesRead / (float)BufferWidth);
 | 
			
		||||
    Ret.Y += Step;
 | 
			
		||||
    // Partial row
 | 
			
		||||
    Ret.X = BytesRead - (BufferWidth * Step);
 | 
			
		||||
    return Ret;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	// Check size
 | 
			
		||||
	if (Width < 8 || Height < 12) return;
 | 
			
		||||
    // Check size
 | 
			
		||||
    if (Width < 8 || Height < 12) return;
 | 
			
		||||
 | 
			
		||||
	bool DBef = true;
 | 
			
		||||
	bool DAft = true;
 | 
			
		||||
	std::string SLog = "";
 | 
			
		||||
    bool DBef = true;
 | 
			
		||||
    bool DAft = true;
 | 
			
		||||
    std::string SLog = "";
 | 
			
		||||
 | 
			
		||||
	const HWND hWnd = GetConsoleWindow();
 | 
			
		||||
	const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
 | 
			
		||||
    const HWND hWnd = GetConsoleWindow();
 | 
			
		||||
    const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
 | 
			
		||||
 | 
			
		||||
	// Get console info
 | 
			
		||||
	CONSOLE_SCREEN_BUFFER_INFO ConInfo;
 | 
			
		||||
	GetConsoleScreenBufferInfo(hConsole, &ConInfo);
 | 
			
		||||
	DWORD BufferSize = ConInfo.dwSize.X * ConInfo.dwSize.Y;
 | 
			
		||||
    // Get console info
 | 
			
		||||
    CONSOLE_SCREEN_BUFFER_INFO ConInfo;
 | 
			
		||||
    GetConsoleScreenBufferInfo(hConsole, &ConInfo);
 | 
			
		||||
    DWORD BufferSize = ConInfo.dwSize.X * ConInfo.dwSize.Y;
 | 
			
		||||
 | 
			
		||||
	// ---------------------------------------------------------------------
 | 
			
		||||
	//  Save the current text
 | 
			
		||||
	// ------------------------
 | 
			
		||||
	DWORD cCharsRead = 0;
 | 
			
		||||
	COORD coordScreen = { 0, 0 };
 | 
			
		||||
    // ---------------------------------------------------------------------
 | 
			
		||||
    //  Save the current text
 | 
			
		||||
    // ------------------------
 | 
			
		||||
    DWORD cCharsRead = 0;
 | 
			
		||||
    COORD coordScreen = { 0, 0 };
 | 
			
		||||
 | 
			
		||||
	static const int MAX_BYTES = 1024 * 16;
 | 
			
		||||
    static const int MAX_BYTES = 1024 * 16;
 | 
			
		||||
 | 
			
		||||
	std::vector<std::array<TCHAR, MAX_BYTES>> Str;
 | 
			
		||||
	std::vector<std::array<WORD, MAX_BYTES>> Attr;
 | 
			
		||||
    std::vector<std::array<TCHAR, MAX_BYTES>> Str;
 | 
			
		||||
    std::vector<std::array<WORD, MAX_BYTES>> Attr;
 | 
			
		||||
 | 
			
		||||
	// ReadConsoleOutputAttribute seems to have a limit at this level
 | 
			
		||||
	static const int ReadBufferSize = MAX_BYTES - 32;
 | 
			
		||||
    // ReadConsoleOutputAttribute seems to have a limit at this level
 | 
			
		||||
    static const int ReadBufferSize = MAX_BYTES - 32;
 | 
			
		||||
 | 
			
		||||
	DWORD cAttrRead = ReadBufferSize;
 | 
			
		||||
	DWORD BytesRead = 0;
 | 
			
		||||
	while (BytesRead < BufferSize)
 | 
			
		||||
	{
 | 
			
		||||
		Str.resize(Str.size() + 1);
 | 
			
		||||
		if (!ReadConsoleOutputCharacter(hConsole, Str.back().data(), ReadBufferSize, coordScreen, &cCharsRead))
 | 
			
		||||
			SLog += StringFromFormat("WriteConsoleOutputCharacter error");
 | 
			
		||||
    DWORD cAttrRead = ReadBufferSize;
 | 
			
		||||
    DWORD BytesRead = 0;
 | 
			
		||||
    while (BytesRead < BufferSize)
 | 
			
		||||
    {
 | 
			
		||||
        Str.resize(Str.size() + 1);
 | 
			
		||||
        if (!ReadConsoleOutputCharacter(hConsole, Str.back().data(), ReadBufferSize, coordScreen, &cCharsRead))
 | 
			
		||||
            SLog += StringFromFormat("WriteConsoleOutputCharacter error");
 | 
			
		||||
 | 
			
		||||
		Attr.resize(Attr.size() + 1);
 | 
			
		||||
		if (!ReadConsoleOutputAttribute(hConsole, Attr.back().data(), ReadBufferSize, coordScreen, &cAttrRead))
 | 
			
		||||
			SLog += StringFromFormat("WriteConsoleOutputAttribute error");
 | 
			
		||||
        Attr.resize(Attr.size() + 1);
 | 
			
		||||
        if (!ReadConsoleOutputAttribute(hConsole, Attr.back().data(), ReadBufferSize, coordScreen, &cAttrRead))
 | 
			
		||||
            SLog += StringFromFormat("WriteConsoleOutputAttribute error");
 | 
			
		||||
 | 
			
		||||
		// Break on error
 | 
			
		||||
		if (cAttrRead == 0) break;
 | 
			
		||||
		BytesRead += cAttrRead;
 | 
			
		||||
		coordScreen = GetCoordinates(BytesRead, ConInfo.dwSize.X);
 | 
			
		||||
	}
 | 
			
		||||
	// Letter space
 | 
			
		||||
	int LWidth = (int)(floor((float)Width / 8.0f) - 1.0f);
 | 
			
		||||
	int LHeight = (int)(floor((float)Height / 12.0f) - 1.0f);
 | 
			
		||||
	int LBufWidth = LWidth + 1;
 | 
			
		||||
	int LBufHeight = (int)floor((float)BufferSize / (float)LBufWidth);
 | 
			
		||||
	// Change screen buffer size
 | 
			
		||||
	LetterSpace(LBufWidth, LBufHeight);
 | 
			
		||||
        // Break on error
 | 
			
		||||
        if (cAttrRead == 0) break;
 | 
			
		||||
        BytesRead += cAttrRead;
 | 
			
		||||
        coordScreen = GetCoordinates(BytesRead, ConInfo.dwSize.X);
 | 
			
		||||
    }
 | 
			
		||||
    // Letter space
 | 
			
		||||
    int LWidth = (int)(floor((float)Width / 8.0f) - 1.0f);
 | 
			
		||||
    int LHeight = (int)(floor((float)Height / 12.0f) - 1.0f);
 | 
			
		||||
    int LBufWidth = LWidth + 1;
 | 
			
		||||
    int LBufHeight = (int)floor((float)BufferSize / (float)LBufWidth);
 | 
			
		||||
    // Change screen buffer size
 | 
			
		||||
    LetterSpace(LBufWidth, LBufHeight);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	ClearScreen(true);
 | 
			
		||||
	coordScreen.Y = 0;
 | 
			
		||||
	coordScreen.X = 0;
 | 
			
		||||
	DWORD cCharsWritten = 0;
 | 
			
		||||
    ClearScreen(true);
 | 
			
		||||
    coordScreen.Y = 0;
 | 
			
		||||
    coordScreen.X = 0;
 | 
			
		||||
    DWORD cCharsWritten = 0;
 | 
			
		||||
 | 
			
		||||
	int BytesWritten = 0;
 | 
			
		||||
	DWORD cAttrWritten = 0;
 | 
			
		||||
	for (size_t i = 0; i < Attr.size(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		if (!WriteConsoleOutputCharacter(hConsole, Str[i].data(), ReadBufferSize, coordScreen, &cCharsWritten))
 | 
			
		||||
			SLog += StringFromFormat("WriteConsoleOutputCharacter error");
 | 
			
		||||
		if (!WriteConsoleOutputAttribute(hConsole, Attr[i].data(), ReadBufferSize, coordScreen, &cAttrWritten))
 | 
			
		||||
			SLog += StringFromFormat("WriteConsoleOutputAttribute error");
 | 
			
		||||
    int BytesWritten = 0;
 | 
			
		||||
    DWORD cAttrWritten = 0;
 | 
			
		||||
    for (size_t i = 0; i < Attr.size(); i++)
 | 
			
		||||
    {
 | 
			
		||||
        if (!WriteConsoleOutputCharacter(hConsole, Str[i].data(), ReadBufferSize, coordScreen, &cCharsWritten))
 | 
			
		||||
            SLog += StringFromFormat("WriteConsoleOutputCharacter error");
 | 
			
		||||
        if (!WriteConsoleOutputAttribute(hConsole, Attr[i].data(), ReadBufferSize, coordScreen, &cAttrWritten))
 | 
			
		||||
            SLog += StringFromFormat("WriteConsoleOutputAttribute error");
 | 
			
		||||
 | 
			
		||||
		BytesWritten += cAttrWritten;
 | 
			
		||||
		coordScreen = GetCoordinates(BytesWritten, LBufWidth);
 | 
			
		||||
	}	
 | 
			
		||||
        BytesWritten += cAttrWritten;
 | 
			
		||||
        coordScreen = GetCoordinates(BytesWritten, LBufWidth);
 | 
			
		||||
    }    
 | 
			
		||||
 | 
			
		||||
	const int OldCursor = ConInfo.dwCursorPosition.Y * ConInfo.dwSize.X + ConInfo.dwCursorPosition.X;
 | 
			
		||||
	COORD Coo = GetCoordinates(OldCursor, LBufWidth);
 | 
			
		||||
	SetConsoleCursorPosition(hConsole, Coo);
 | 
			
		||||
    const int OldCursor = ConInfo.dwCursorPosition.Y * ConInfo.dwSize.X + ConInfo.dwCursorPosition.X;
 | 
			
		||||
    COORD Coo = GetCoordinates(OldCursor, LBufWidth);
 | 
			
		||||
    SetConsoleCursorPosition(hConsole, Coo);
 | 
			
		||||
 | 
			
		||||
	if (SLog.length() > 0) Log(LogTypes::LNOTICE, SLog.c_str());
 | 
			
		||||
    if (SLog.length() > 0) Log(LogTypes::LNOTICE, SLog.c_str());
 | 
			
		||||
 | 
			
		||||
	// Resize the window too
 | 
			
		||||
	if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 100),Height, true);
 | 
			
		||||
    // Resize the window too
 | 
			
		||||
    if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 100),Height, true);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text)
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
	/*
 | 
			
		||||
	const int MAX_BYTES = 1024*10;
 | 
			
		||||
	char Str[MAX_BYTES];
 | 
			
		||||
	va_list ArgPtr;
 | 
			
		||||
	int Cnt;
 | 
			
		||||
	va_start(ArgPtr, Text);
 | 
			
		||||
	Cnt = vsnprintf(Str, MAX_BYTES, Text, ArgPtr);
 | 
			
		||||
	va_end(ArgPtr);
 | 
			
		||||
	*/
 | 
			
		||||
	DWORD cCharsWritten;
 | 
			
		||||
	WORD Color;
 | 
			
		||||
    /*
 | 
			
		||||
    const int MAX_BYTES = 1024*10;
 | 
			
		||||
    char Str[MAX_BYTES];
 | 
			
		||||
    va_list ArgPtr;
 | 
			
		||||
    int Cnt;
 | 
			
		||||
    va_start(ArgPtr, Text);
 | 
			
		||||
    Cnt = vsnprintf(Str, MAX_BYTES, Text, ArgPtr);
 | 
			
		||||
    va_end(ArgPtr);
 | 
			
		||||
    */
 | 
			
		||||
    DWORD cCharsWritten;
 | 
			
		||||
    WORD Color;
 | 
			
		||||
 | 
			
		||||
	switch (Level)
 | 
			
		||||
	{
 | 
			
		||||
	case NOTICE_LEVEL: // light green
 | 
			
		||||
		Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
 | 
			
		||||
		break;
 | 
			
		||||
	case ERROR_LEVEL: // light red
 | 
			
		||||
		Color = FOREGROUND_RED | FOREGROUND_INTENSITY;
 | 
			
		||||
		break;
 | 
			
		||||
	case WARNING_LEVEL: // light yellow
 | 
			
		||||
		Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
 | 
			
		||||
		break;
 | 
			
		||||
	case INFO_LEVEL: // cyan
 | 
			
		||||
		Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
 | 
			
		||||
		break;
 | 
			
		||||
	case DEBUG_LEVEL: // gray
 | 
			
		||||
		Color = FOREGROUND_INTENSITY;
 | 
			
		||||
		break;
 | 
			
		||||
	default: // off-white
 | 
			
		||||
		Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	if (strlen(Text) > 10)
 | 
			
		||||
	{
 | 
			
		||||
		// First 10 chars white
 | 
			
		||||
		SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
 | 
			
		||||
		WriteConsole(hConsole, Text, 10, &cCharsWritten, NULL);
 | 
			
		||||
		Text += 10;
 | 
			
		||||
	}
 | 
			
		||||
	SetConsoleTextAttribute(hConsole, Color);
 | 
			
		||||
	WriteConsole(hConsole, Text, (DWORD)strlen(Text), &cCharsWritten, NULL);
 | 
			
		||||
    switch (Level)
 | 
			
		||||
    {
 | 
			
		||||
    case NOTICE_LEVEL: // light green
 | 
			
		||||
        Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
 | 
			
		||||
        break;
 | 
			
		||||
    case ERROR_LEVEL: // light red
 | 
			
		||||
        Color = FOREGROUND_RED | FOREGROUND_INTENSITY;
 | 
			
		||||
        break;
 | 
			
		||||
    case WARNING_LEVEL: // light yellow
 | 
			
		||||
        Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
 | 
			
		||||
        break;
 | 
			
		||||
    case INFO_LEVEL: // cyan
 | 
			
		||||
        Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
 | 
			
		||||
        break;
 | 
			
		||||
    case DEBUG_LEVEL: // gray
 | 
			
		||||
        Color = FOREGROUND_INTENSITY;
 | 
			
		||||
        break;
 | 
			
		||||
    default: // off-white
 | 
			
		||||
        Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    if (strlen(Text) > 10)
 | 
			
		||||
    {
 | 
			
		||||
        // First 10 chars white
 | 
			
		||||
        SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
 | 
			
		||||
        WriteConsole(hConsole, Text, 10, &cCharsWritten, NULL);
 | 
			
		||||
        Text += 10;
 | 
			
		||||
    }
 | 
			
		||||
    SetConsoleTextAttribute(hConsole, Color);
 | 
			
		||||
    WriteConsole(hConsole, Text, (DWORD)strlen(Text), &cCharsWritten, NULL);
 | 
			
		||||
#else
 | 
			
		||||
	char ColorAttr[16] = "";
 | 
			
		||||
	char ResetAttr[16] = "";
 | 
			
		||||
    char ColorAttr[16] = "";
 | 
			
		||||
    char ResetAttr[16] = "";
 | 
			
		||||
 | 
			
		||||
	if (bUseColor)
 | 
			
		||||
	{
 | 
			
		||||
		strcpy(ResetAttr, "\033[0m");
 | 
			
		||||
		switch (Level)
 | 
			
		||||
		{
 | 
			
		||||
		case NOTICE_LEVEL: // light green
 | 
			
		||||
			strcpy(ColorAttr, "\033[92m");
 | 
			
		||||
			break;
 | 
			
		||||
		case ERROR_LEVEL: // light red
 | 
			
		||||
			strcpy(ColorAttr, "\033[91m");
 | 
			
		||||
			break;
 | 
			
		||||
		case WARNING_LEVEL: // light yellow
 | 
			
		||||
			strcpy(ColorAttr, "\033[93m");
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	fprintf(stderr, "%s%s%s", ColorAttr, Text, ResetAttr);
 | 
			
		||||
    if (bUseColor)
 | 
			
		||||
    {
 | 
			
		||||
        strcpy(ResetAttr, "\033[0m");
 | 
			
		||||
        switch (Level)
 | 
			
		||||
        {
 | 
			
		||||
        case NOTICE_LEVEL: // light green
 | 
			
		||||
            strcpy(ColorAttr, "\033[92m");
 | 
			
		||||
            break;
 | 
			
		||||
        case ERROR_LEVEL: // light red
 | 
			
		||||
            strcpy(ColorAttr, "\033[91m");
 | 
			
		||||
            break;
 | 
			
		||||
        case WARNING_LEVEL: // light yellow
 | 
			
		||||
            strcpy(ColorAttr, "\033[93m");
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    fprintf(stderr, "%s%s%s", ColorAttr, Text, ResetAttr);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
// Clear console screen
 | 
			
		||||
void ConsoleListener::ClearScreen(bool Cursor)
 | 
			
		||||
{ 
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
	COORD coordScreen = { 0, 0 }; 
 | 
			
		||||
	DWORD cCharsWritten; 
 | 
			
		||||
	CONSOLE_SCREEN_BUFFER_INFO csbi; 
 | 
			
		||||
	DWORD dwConSize; 
 | 
			
		||||
    COORD coordScreen = { 0, 0 }; 
 | 
			
		||||
    DWORD cCharsWritten; 
 | 
			
		||||
    CONSOLE_SCREEN_BUFFER_INFO csbi; 
 | 
			
		||||
    DWORD dwConSize; 
 | 
			
		||||
 | 
			
		||||
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 
 | 
			
		||||
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 
 | 
			
		||||
 | 
			
		||||
	GetConsoleScreenBufferInfo(hConsole, &csbi); 
 | 
			
		||||
	dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
 | 
			
		||||
	// Write space to the entire console
 | 
			
		||||
	FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten); 
 | 
			
		||||
	GetConsoleScreenBufferInfo(hConsole, &csbi); 
 | 
			
		||||
	FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
 | 
			
		||||
	// Reset cursor
 | 
			
		||||
	if (Cursor) SetConsoleCursorPosition(hConsole, coordScreen); 
 | 
			
		||||
    GetConsoleScreenBufferInfo(hConsole, &csbi); 
 | 
			
		||||
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
 | 
			
		||||
    // Write space to the entire console
 | 
			
		||||
    FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten); 
 | 
			
		||||
    GetConsoleScreenBufferInfo(hConsole, &csbi); 
 | 
			
		||||
    FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
 | 
			
		||||
    // Reset cursor
 | 
			
		||||
    if (Cursor) SetConsoleCursorPosition(hConsole, coordScreen); 
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,28 +14,28 @@
 | 
			
		||||
class ConsoleListener : public LogListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	ConsoleListener();
 | 
			
		||||
	~ConsoleListener();
 | 
			
		||||
    ConsoleListener();
 | 
			
		||||
    ~ConsoleListener();
 | 
			
		||||
 | 
			
		||||
	void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console");
 | 
			
		||||
	void UpdateHandle();
 | 
			
		||||
	void Close();
 | 
			
		||||
	bool IsOpen();
 | 
			
		||||
	void LetterSpace(int Width, int Height);
 | 
			
		||||
	void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst);
 | 
			
		||||
	void PixelSpace(int Left, int Top, int Width, int Height, bool);
 | 
			
		||||
    void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console");
 | 
			
		||||
    void UpdateHandle();
 | 
			
		||||
    void Close();
 | 
			
		||||
    bool IsOpen();
 | 
			
		||||
    void LetterSpace(int Width, int Height);
 | 
			
		||||
    void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst);
 | 
			
		||||
    void PixelSpace(int Left, int Top, int Width, int Height, bool);
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	COORD GetCoordinates(int BytesRead, int BufferWidth);
 | 
			
		||||
    COORD GetCoordinates(int BytesRead, int BufferWidth);
 | 
			
		||||
#endif
 | 
			
		||||
	void Log(LogTypes::LOG_LEVELS, const char *Text);
 | 
			
		||||
	void ClearScreen(bool Cursor = true);
 | 
			
		||||
    void Log(LogTypes::LOG_LEVELS, const char *Text);
 | 
			
		||||
    void ClearScreen(bool Cursor = true);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	HWND GetHwnd(void);
 | 
			
		||||
	HANDLE hConsole;
 | 
			
		||||
    HWND GetHwnd(void);
 | 
			
		||||
    HANDLE hConsole;
 | 
			
		||||
#endif
 | 
			
		||||
	bool bUseColor;
 | 
			
		||||
    bool bUseColor;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif  // _CONSOLELISTENER_H
 | 
			
		||||
 
 | 
			
		||||
@@ -11,69 +11,69 @@
 | 
			
		||||
 | 
			
		||||
enum CPUVendor
 | 
			
		||||
{
 | 
			
		||||
	VENDOR_INTEL = 0,
 | 
			
		||||
	VENDOR_AMD = 1,
 | 
			
		||||
	VENDOR_ARM = 2,
 | 
			
		||||
	VENDOR_OTHER = 3,
 | 
			
		||||
    VENDOR_INTEL = 0,
 | 
			
		||||
    VENDOR_AMD = 1,
 | 
			
		||||
    VENDOR_ARM = 2,
 | 
			
		||||
    VENDOR_OTHER = 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct CPUInfo
 | 
			
		||||
{
 | 
			
		||||
	CPUVendor vendor;
 | 
			
		||||
    CPUVendor vendor;
 | 
			
		||||
 | 
			
		||||
	char cpu_string[0x21];
 | 
			
		||||
	char brand_string[0x41];
 | 
			
		||||
	bool OS64bit;
 | 
			
		||||
	bool CPU64bit;
 | 
			
		||||
	bool Mode64bit;
 | 
			
		||||
    char cpu_string[0x21];
 | 
			
		||||
    char brand_string[0x41];
 | 
			
		||||
    bool OS64bit;
 | 
			
		||||
    bool CPU64bit;
 | 
			
		||||
    bool Mode64bit;
 | 
			
		||||
 | 
			
		||||
	bool HTT;
 | 
			
		||||
	int num_cores;
 | 
			
		||||
	int logical_cpu_count;
 | 
			
		||||
    bool HTT;
 | 
			
		||||
    int num_cores;
 | 
			
		||||
    int logical_cpu_count;
 | 
			
		||||
 | 
			
		||||
	bool bSSE;
 | 
			
		||||
	bool bSSE2;
 | 
			
		||||
	bool bSSE3;
 | 
			
		||||
	bool bSSSE3;
 | 
			
		||||
	bool bPOPCNT;
 | 
			
		||||
	bool bSSE4_1;
 | 
			
		||||
	bool bSSE4_2;
 | 
			
		||||
	bool bLZCNT;
 | 
			
		||||
	bool bSSE4A;
 | 
			
		||||
	bool bAVX;
 | 
			
		||||
	bool bAES;
 | 
			
		||||
	bool bLAHFSAHF64;
 | 
			
		||||
	bool bLongMode;
 | 
			
		||||
    bool bSSE;
 | 
			
		||||
    bool bSSE2;
 | 
			
		||||
    bool bSSE3;
 | 
			
		||||
    bool bSSSE3;
 | 
			
		||||
    bool bPOPCNT;
 | 
			
		||||
    bool bSSE4_1;
 | 
			
		||||
    bool bSSE4_2;
 | 
			
		||||
    bool bLZCNT;
 | 
			
		||||
    bool bSSE4A;
 | 
			
		||||
    bool bAVX;
 | 
			
		||||
    bool bAES;
 | 
			
		||||
    bool bLAHFSAHF64;
 | 
			
		||||
    bool bLongMode;
 | 
			
		||||
 | 
			
		||||
	// ARM specific CPUInfo
 | 
			
		||||
	bool bSwp;
 | 
			
		||||
	bool bHalf;
 | 
			
		||||
	bool bThumb;
 | 
			
		||||
	bool bFastMult;
 | 
			
		||||
	bool bVFP;
 | 
			
		||||
	bool bEDSP;
 | 
			
		||||
	bool bThumbEE;
 | 
			
		||||
	bool bNEON;
 | 
			
		||||
	bool bVFPv3;
 | 
			
		||||
	bool bTLS;
 | 
			
		||||
	bool bVFPv4;
 | 
			
		||||
	bool bIDIVa;
 | 
			
		||||
	bool bIDIVt;
 | 
			
		||||
	bool bArmV7;  // enable MOVT, MOVW etc
 | 
			
		||||
    // ARM specific CPUInfo
 | 
			
		||||
    bool bSwp;
 | 
			
		||||
    bool bHalf;
 | 
			
		||||
    bool bThumb;
 | 
			
		||||
    bool bFastMult;
 | 
			
		||||
    bool bVFP;
 | 
			
		||||
    bool bEDSP;
 | 
			
		||||
    bool bThumbEE;
 | 
			
		||||
    bool bNEON;
 | 
			
		||||
    bool bVFPv3;
 | 
			
		||||
    bool bTLS;
 | 
			
		||||
    bool bVFPv4;
 | 
			
		||||
    bool bIDIVa;
 | 
			
		||||
    bool bIDIVt;
 | 
			
		||||
    bool bArmV7;  // enable MOVT, MOVW etc
 | 
			
		||||
 | 
			
		||||
	// ARMv8 specific
 | 
			
		||||
	bool bFP;
 | 
			
		||||
	bool bASIMD;
 | 
			
		||||
    // ARMv8 specific
 | 
			
		||||
    bool bFP;
 | 
			
		||||
    bool bASIMD;
 | 
			
		||||
 | 
			
		||||
	// Call Detect()
 | 
			
		||||
	explicit CPUInfo();
 | 
			
		||||
    // Call Detect()
 | 
			
		||||
    explicit CPUInfo();
 | 
			
		||||
 | 
			
		||||
	// Turn the cpu info into a string we can show
 | 
			
		||||
	std::string Summarize();
 | 
			
		||||
    // Turn the cpu info into a string we can show
 | 
			
		||||
    std::string Summarize();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	// Detects the various cpu features
 | 
			
		||||
	void Detect();
 | 
			
		||||
    // Detects the various cpu features
 | 
			
		||||
    void Detect();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern CPUInfo cpu_info;
 | 
			
		||||
 
 | 
			
		||||
@@ -7,33 +7,33 @@
 | 
			
		||||
class DebugInterface
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
	virtual ~DebugInterface() {}
 | 
			
		||||
    virtual ~DebugInterface() {}
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	virtual void disasm(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");}
 | 
			
		||||
	virtual void getRawMemoryString(int /*memory*/, unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");}
 | 
			
		||||
	virtual int getInstructionSize(int /*instruction*/) {return 1;}
 | 
			
		||||
	virtual bool isAlive() {return true;}
 | 
			
		||||
	virtual bool isBreakpoint(unsigned int /*address*/) {return false;}
 | 
			
		||||
	virtual void setBreakpoint(unsigned int /*address*/){}
 | 
			
		||||
	virtual void clearBreakpoint(unsigned int /*address*/){}
 | 
			
		||||
	virtual void clearAllBreakpoints() {}
 | 
			
		||||
	virtual void toggleBreakpoint(unsigned int /*address*/){}
 | 
			
		||||
	virtual bool isMemCheck(unsigned int /*address*/) {return false;}
 | 
			
		||||
	virtual void toggleMemCheck(unsigned int /*address*/){}
 | 
			
		||||
	virtual unsigned int readMemory(unsigned int /*address*/){return 0;}
 | 
			
		||||
	virtual void writeExtraMemory(int /*memory*/, unsigned int /*value*/, unsigned int /*address*/) {}
 | 
			
		||||
	virtual unsigned int readExtraMemory(int /*memory*/, unsigned int /*address*/){return 0;}
 | 
			
		||||
	virtual unsigned int readInstruction(unsigned int /*address*/){return 0;}
 | 
			
		||||
	virtual unsigned int getPC() {return 0;}
 | 
			
		||||
	virtual void setPC(unsigned int /*address*/) {}
 | 
			
		||||
	virtual void step() {}
 | 
			
		||||
	virtual void runToBreakpoint() {}
 | 
			
		||||
	virtual void breakNow() {}
 | 
			
		||||
	virtual void insertBLR(unsigned int /*address*/, unsigned int /*value*/) {}
 | 
			
		||||
	virtual void showJitResults(unsigned int /*address*/) {};
 | 
			
		||||
	virtual int getColor(unsigned int /*address*/){return 0xFFFFFFFF;}
 | 
			
		||||
	virtual std::string getDescription(unsigned int /*address*/) = 0;
 | 
			
		||||
    virtual void disasm(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");}
 | 
			
		||||
    virtual void getRawMemoryString(int /*memory*/, unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");}
 | 
			
		||||
    virtual int getInstructionSize(int /*instruction*/) {return 1;}
 | 
			
		||||
    virtual bool isAlive() {return true;}
 | 
			
		||||
    virtual bool isBreakpoint(unsigned int /*address*/) {return false;}
 | 
			
		||||
    virtual void setBreakpoint(unsigned int /*address*/){}
 | 
			
		||||
    virtual void clearBreakpoint(unsigned int /*address*/){}
 | 
			
		||||
    virtual void clearAllBreakpoints() {}
 | 
			
		||||
    virtual void toggleBreakpoint(unsigned int /*address*/){}
 | 
			
		||||
    virtual bool isMemCheck(unsigned int /*address*/) {return false;}
 | 
			
		||||
    virtual void toggleMemCheck(unsigned int /*address*/){}
 | 
			
		||||
    virtual unsigned int readMemory(unsigned int /*address*/){return 0;}
 | 
			
		||||
    virtual void writeExtraMemory(int /*memory*/, unsigned int /*value*/, unsigned int /*address*/) {}
 | 
			
		||||
    virtual unsigned int readExtraMemory(int /*memory*/, unsigned int /*address*/){return 0;}
 | 
			
		||||
    virtual unsigned int readInstruction(unsigned int /*address*/){return 0;}
 | 
			
		||||
    virtual unsigned int getPC() {return 0;}
 | 
			
		||||
    virtual void setPC(unsigned int /*address*/) {}
 | 
			
		||||
    virtual void step() {}
 | 
			
		||||
    virtual void runToBreakpoint() {}
 | 
			
		||||
    virtual void breakNow() {}
 | 
			
		||||
    virtual void insertBLR(unsigned int /*address*/, unsigned int /*value*/) {}
 | 
			
		||||
    virtual void showJitResults(unsigned int /*address*/) {};
 | 
			
		||||
    virtual int getColor(unsigned int /*address*/){return 0xFFFFFFFF;}
 | 
			
		||||
    virtual std::string getDescription(unsigned int /*address*/) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -48,8 +48,8 @@ public:
 | 
			
		||||
    /// Swap buffers to display the next frame
 | 
			
		||||
    virtual void SwapBuffers() = 0;
 | 
			
		||||
 | 
			
		||||
	/// Polls window events
 | 
			
		||||
	virtual void PollEvents() = 0;
 | 
			
		||||
    /// Polls window events
 | 
			
		||||
    virtual void PollEvents() = 0;
 | 
			
		||||
 | 
			
		||||
    /// Makes the graphics context current for the caller thread
 | 
			
		||||
    virtual void MakeCurrent() = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -30,18 +30,18 @@ using namespace std;
 | 
			
		||||
void PCSTR2LPTSTR( PCSTR lpszIn, LPTSTR lpszOut )
 | 
			
		||||
{
 | 
			
		||||
#if defined(UNICODE)||defined(_UNICODE)
 | 
			
		||||
	ULONG index = 0; 
 | 
			
		||||
	PCSTR lpAct = lpszIn;
 | 
			
		||||
    ULONG index = 0; 
 | 
			
		||||
    PCSTR lpAct = lpszIn;
 | 
			
		||||
 | 
			
		||||
	for( ; ; lpAct++ )
 | 
			
		||||
	{
 | 
			
		||||
		lpszOut[index++] = (TCHAR)(*lpAct);
 | 
			
		||||
		if ( *lpAct == 0 )
 | 
			
		||||
			break;
 | 
			
		||||
	} 
 | 
			
		||||
    for( ; ; lpAct++ )
 | 
			
		||||
    {
 | 
			
		||||
        lpszOut[index++] = (TCHAR)(*lpAct);
 | 
			
		||||
        if ( *lpAct == 0 )
 | 
			
		||||
            break;
 | 
			
		||||
    } 
 | 
			
		||||
#else
 | 
			
		||||
	// This is trivial :)
 | 
			
		||||
	strcpy( lpszOut, lpszIn );
 | 
			
		||||
    // This is trivial :)
 | 
			
		||||
    strcpy( lpszOut, lpszIn );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -50,184 +50,184 @@ void PCSTR2LPTSTR( PCSTR lpszIn, LPTSTR lpszOut )
 | 
			
		||||
// Note: There is no size check for lpszSymbolPath!
 | 
			
		||||
static void InitSymbolPath( PSTR lpszSymbolPath, PCSTR lpszIniPath )
 | 
			
		||||
{
 | 
			
		||||
	CHAR lpszPath[BUFFERSIZE];
 | 
			
		||||
    CHAR lpszPath[BUFFERSIZE];
 | 
			
		||||
 | 
			
		||||
	// Creating the default path
 | 
			
		||||
	// ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%SYSTEMROOT%;%SYSTEMROOT%\System32;"
 | 
			
		||||
	strcpy( lpszSymbolPath, "." );
 | 
			
		||||
    // Creating the default path
 | 
			
		||||
    // ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%SYSTEMROOT%;%SYSTEMROOT%\System32;"
 | 
			
		||||
    strcpy( lpszSymbolPath, "." );
 | 
			
		||||
 | 
			
		||||
	// environment variable _NT_SYMBOL_PATH
 | 
			
		||||
	if ( GetEnvironmentVariableA( "_NT_SYMBOL_PATH", lpszPath, BUFFERSIZE ) )
 | 
			
		||||
	{
 | 
			
		||||
		strcat( lpszSymbolPath, ";" );
 | 
			
		||||
		strcat( lpszSymbolPath, lpszPath );
 | 
			
		||||
	}
 | 
			
		||||
    // environment variable _NT_SYMBOL_PATH
 | 
			
		||||
    if ( GetEnvironmentVariableA( "_NT_SYMBOL_PATH", lpszPath, BUFFERSIZE ) )
 | 
			
		||||
    {
 | 
			
		||||
        strcat( lpszSymbolPath, ";" );
 | 
			
		||||
        strcat( lpszSymbolPath, lpszPath );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// environment variable _NT_ALTERNATE_SYMBOL_PATH
 | 
			
		||||
	if ( GetEnvironmentVariableA( "_NT_ALTERNATE_SYMBOL_PATH", lpszPath, BUFFERSIZE ) )
 | 
			
		||||
	{
 | 
			
		||||
		strcat( lpszSymbolPath, ";" );
 | 
			
		||||
		strcat( lpszSymbolPath, lpszPath );
 | 
			
		||||
	}
 | 
			
		||||
    // environment variable _NT_ALTERNATE_SYMBOL_PATH
 | 
			
		||||
    if ( GetEnvironmentVariableA( "_NT_ALTERNATE_SYMBOL_PATH", lpszPath, BUFFERSIZE ) )
 | 
			
		||||
    {
 | 
			
		||||
        strcat( lpszSymbolPath, ";" );
 | 
			
		||||
        strcat( lpszSymbolPath, lpszPath );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// environment variable SYSTEMROOT
 | 
			
		||||
	if ( GetEnvironmentVariableA( "SYSTEMROOT", lpszPath, BUFFERSIZE ) )
 | 
			
		||||
	{
 | 
			
		||||
		strcat( lpszSymbolPath, ";" );
 | 
			
		||||
		strcat( lpszSymbolPath, lpszPath );
 | 
			
		||||
		strcat( lpszSymbolPath, ";" );
 | 
			
		||||
    // environment variable SYSTEMROOT
 | 
			
		||||
    if ( GetEnvironmentVariableA( "SYSTEMROOT", lpszPath, BUFFERSIZE ) )
 | 
			
		||||
    {
 | 
			
		||||
        strcat( lpszSymbolPath, ";" );
 | 
			
		||||
        strcat( lpszSymbolPath, lpszPath );
 | 
			
		||||
        strcat( lpszSymbolPath, ";" );
 | 
			
		||||
 | 
			
		||||
		// SYSTEMROOT\System32
 | 
			
		||||
		strcat( lpszSymbolPath, lpszPath );
 | 
			
		||||
		strcat( lpszSymbolPath, "\\System32" );
 | 
			
		||||
	}
 | 
			
		||||
        // SYSTEMROOT\System32
 | 
			
		||||
        strcat( lpszSymbolPath, lpszPath );
 | 
			
		||||
        strcat( lpszSymbolPath, "\\System32" );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// Add user defined path
 | 
			
		||||
	if ( lpszIniPath != NULL )
 | 
			
		||||
		if ( lpszIniPath[0] != '\0' )
 | 
			
		||||
		{
 | 
			
		||||
			strcat( lpszSymbolPath, ";" );
 | 
			
		||||
			strcat( lpszSymbolPath, lpszIniPath );
 | 
			
		||||
		}
 | 
			
		||||
    // Add user defined path
 | 
			
		||||
    if ( lpszIniPath != NULL )
 | 
			
		||||
        if ( lpszIniPath[0] != '\0' )
 | 
			
		||||
        {
 | 
			
		||||
            strcat( lpszSymbolPath, ";" );
 | 
			
		||||
            strcat( lpszSymbolPath, lpszIniPath );
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uninitialize the loaded symbol files
 | 
			
		||||
BOOL UninitSymInfo() {
 | 
			
		||||
	return SymCleanup( GetCurrentProcess() );
 | 
			
		||||
    return SymCleanup( GetCurrentProcess() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Initializes the symbol files
 | 
			
		||||
BOOL InitSymInfo( PCSTR lpszInitialSymbolPath )
 | 
			
		||||
{
 | 
			
		||||
	CHAR     lpszSymbolPath[BUFFERSIZE];
 | 
			
		||||
	DWORD    symOptions = SymGetOptions();
 | 
			
		||||
    CHAR     lpszSymbolPath[BUFFERSIZE];
 | 
			
		||||
    DWORD    symOptions = SymGetOptions();
 | 
			
		||||
 | 
			
		||||
	symOptions |= SYMOPT_LOAD_LINES; 
 | 
			
		||||
	symOptions &= ~SYMOPT_UNDNAME;
 | 
			
		||||
	SymSetOptions( symOptions );
 | 
			
		||||
	InitSymbolPath( lpszSymbolPath, lpszInitialSymbolPath );
 | 
			
		||||
    symOptions |= SYMOPT_LOAD_LINES; 
 | 
			
		||||
    symOptions &= ~SYMOPT_UNDNAME;
 | 
			
		||||
    SymSetOptions( symOptions );
 | 
			
		||||
    InitSymbolPath( lpszSymbolPath, lpszInitialSymbolPath );
 | 
			
		||||
 | 
			
		||||
	return SymInitialize( GetCurrentProcess(), lpszSymbolPath, TRUE);
 | 
			
		||||
    return SymInitialize( GetCurrentProcess(), lpszSymbolPath, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get the module name from a given address
 | 
			
		||||
static BOOL GetModuleNameFromAddress( UINT address, LPTSTR lpszModule )
 | 
			
		||||
{
 | 
			
		||||
	BOOL              ret = FALSE;
 | 
			
		||||
	IMAGEHLP_MODULE   moduleInfo;
 | 
			
		||||
    BOOL              ret = FALSE;
 | 
			
		||||
    IMAGEHLP_MODULE   moduleInfo;
 | 
			
		||||
 | 
			
		||||
	::ZeroMemory( &moduleInfo, sizeof(moduleInfo) );
 | 
			
		||||
	moduleInfo.SizeOfStruct = sizeof(moduleInfo);
 | 
			
		||||
    ::ZeroMemory( &moduleInfo, sizeof(moduleInfo) );
 | 
			
		||||
    moduleInfo.SizeOfStruct = sizeof(moduleInfo);
 | 
			
		||||
 | 
			
		||||
	if ( SymGetModuleInfo( GetCurrentProcess(), (DWORD)address, &moduleInfo ) )
 | 
			
		||||
	{
 | 
			
		||||
		// Got it!
 | 
			
		||||
		PCSTR2LPTSTR( moduleInfo.ModuleName, lpszModule );
 | 
			
		||||
		ret = TRUE;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		// Not found :(
 | 
			
		||||
		_tcscpy( lpszModule, _T("?") );
 | 
			
		||||
    if ( SymGetModuleInfo( GetCurrentProcess(), (DWORD)address, &moduleInfo ) )
 | 
			
		||||
    {
 | 
			
		||||
        // Got it!
 | 
			
		||||
        PCSTR2LPTSTR( moduleInfo.ModuleName, lpszModule );
 | 
			
		||||
        ret = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        // Not found :(
 | 
			
		||||
        _tcscpy( lpszModule, _T("?") );
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get function prototype and parameter info from ip address and stack address
 | 
			
		||||
static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, LPTSTR lpszSymbol )
 | 
			
		||||
{
 | 
			
		||||
	BOOL              ret = FALSE;
 | 
			
		||||
	DWORD             dwSymSize = 10000;
 | 
			
		||||
	TCHAR             lpszUnDSymbol[BUFFERSIZE]=_T("?");
 | 
			
		||||
	CHAR              lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?";
 | 
			
		||||
	LPTSTR            lpszParamSep = NULL;
 | 
			
		||||
	LPTSTR            lpszParsed = lpszUnDSymbol;
 | 
			
		||||
	PIMAGEHLP_SYMBOL  pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize );
 | 
			
		||||
    BOOL              ret = FALSE;
 | 
			
		||||
    DWORD             dwSymSize = 10000;
 | 
			
		||||
    TCHAR             lpszUnDSymbol[BUFFERSIZE]=_T("?");
 | 
			
		||||
    CHAR              lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?";
 | 
			
		||||
    LPTSTR            lpszParamSep = NULL;
 | 
			
		||||
    LPTSTR            lpszParsed = lpszUnDSymbol;
 | 
			
		||||
    PIMAGEHLP_SYMBOL  pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize );
 | 
			
		||||
 | 
			
		||||
	::ZeroMemory( pSym, dwSymSize );
 | 
			
		||||
	pSym->SizeOfStruct = dwSymSize;
 | 
			
		||||
	pSym->MaxNameLength = dwSymSize - sizeof(IMAGEHLP_SYMBOL);
 | 
			
		||||
    ::ZeroMemory( pSym, dwSymSize );
 | 
			
		||||
    pSym->SizeOfStruct = dwSymSize;
 | 
			
		||||
    pSym->MaxNameLength = dwSymSize - sizeof(IMAGEHLP_SYMBOL);
 | 
			
		||||
 | 
			
		||||
	// Set the default to unknown
 | 
			
		||||
	_tcscpy( lpszSymbol, _T("?") );
 | 
			
		||||
    // Set the default to unknown
 | 
			
		||||
    _tcscpy( lpszSymbol, _T("?") );
 | 
			
		||||
 | 
			
		||||
	// Get symbol info for IP
 | 
			
		||||
    // Get symbol info for IP
 | 
			
		||||
#ifndef _M_X64
 | 
			
		||||
	DWORD             dwDisp = 0;
 | 
			
		||||
	if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, &dwDisp, pSym ) )
 | 
			
		||||
    DWORD             dwDisp = 0;
 | 
			
		||||
    if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, &dwDisp, pSym ) )
 | 
			
		||||
#else 
 | 
			
		||||
	//makes it compile but hell im not sure if this works...
 | 
			
		||||
	DWORD64           dwDisp = 0;
 | 
			
		||||
	if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) )
 | 
			
		||||
    //makes it compile but hell im not sure if this works...
 | 
			
		||||
    DWORD64           dwDisp = 0;
 | 
			
		||||
    if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) )
 | 
			
		||||
#endif
 | 
			
		||||
	{
 | 
			
		||||
		// Make the symbol readable for humans
 | 
			
		||||
		UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE, 
 | 
			
		||||
			UNDNAME_COMPLETE | 
 | 
			
		||||
			UNDNAME_NO_THISTYPE |
 | 
			
		||||
			UNDNAME_NO_SPECIAL_SYMS |
 | 
			
		||||
			UNDNAME_NO_MEMBER_TYPE |
 | 
			
		||||
			UNDNAME_NO_MS_KEYWORDS |
 | 
			
		||||
			UNDNAME_NO_ACCESS_SPECIFIERS );
 | 
			
		||||
    {
 | 
			
		||||
        // Make the symbol readable for humans
 | 
			
		||||
        UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE, 
 | 
			
		||||
            UNDNAME_COMPLETE | 
 | 
			
		||||
            UNDNAME_NO_THISTYPE |
 | 
			
		||||
            UNDNAME_NO_SPECIAL_SYMS |
 | 
			
		||||
            UNDNAME_NO_MEMBER_TYPE |
 | 
			
		||||
            UNDNAME_NO_MS_KEYWORDS |
 | 
			
		||||
            UNDNAME_NO_ACCESS_SPECIFIERS );
 | 
			
		||||
 | 
			
		||||
		// Symbol information is ANSI string
 | 
			
		||||
		PCSTR2LPTSTR( lpszNonUnicodeUnDSymbol, lpszUnDSymbol );
 | 
			
		||||
        // Symbol information is ANSI string
 | 
			
		||||
        PCSTR2LPTSTR( lpszNonUnicodeUnDSymbol, lpszUnDSymbol );
 | 
			
		||||
 | 
			
		||||
		// I am just smarter than the symbol file :)
 | 
			
		||||
		if ( _tcscmp(lpszUnDSymbol, _T("_WinMain@16")) == 0 )
 | 
			
		||||
			_tcscpy(lpszUnDSymbol, _T("WinMain(HINSTANCE,HINSTANCE,LPCTSTR,int)"));
 | 
			
		||||
		else
 | 
			
		||||
			if ( _tcscmp(lpszUnDSymbol, _T("_main")) == 0 )
 | 
			
		||||
				_tcscpy(lpszUnDSymbol, _T("main(int,TCHAR * *)"));
 | 
			
		||||
			else
 | 
			
		||||
				if ( _tcscmp(lpszUnDSymbol, _T("_mainCRTStartup")) == 0 )
 | 
			
		||||
					_tcscpy(lpszUnDSymbol, _T("mainCRTStartup()"));
 | 
			
		||||
				else
 | 
			
		||||
					if ( _tcscmp(lpszUnDSymbol, _T("_wmain")) == 0 )
 | 
			
		||||
						_tcscpy(lpszUnDSymbol, _T("wmain(int,TCHAR * *,TCHAR * *)"));
 | 
			
		||||
					else
 | 
			
		||||
						if ( _tcscmp(lpszUnDSymbol, _T("_wmainCRTStartup")) == 0 )
 | 
			
		||||
							_tcscpy(lpszUnDSymbol, _T("wmainCRTStartup()"));
 | 
			
		||||
        // I am just smarter than the symbol file :)
 | 
			
		||||
        if ( _tcscmp(lpszUnDSymbol, _T("_WinMain@16")) == 0 )
 | 
			
		||||
            _tcscpy(lpszUnDSymbol, _T("WinMain(HINSTANCE,HINSTANCE,LPCTSTR,int)"));
 | 
			
		||||
        else
 | 
			
		||||
            if ( _tcscmp(lpszUnDSymbol, _T("_main")) == 0 )
 | 
			
		||||
                _tcscpy(lpszUnDSymbol, _T("main(int,TCHAR * *)"));
 | 
			
		||||
            else
 | 
			
		||||
                if ( _tcscmp(lpszUnDSymbol, _T("_mainCRTStartup")) == 0 )
 | 
			
		||||
                    _tcscpy(lpszUnDSymbol, _T("mainCRTStartup()"));
 | 
			
		||||
                else
 | 
			
		||||
                    if ( _tcscmp(lpszUnDSymbol, _T("_wmain")) == 0 )
 | 
			
		||||
                        _tcscpy(lpszUnDSymbol, _T("wmain(int,TCHAR * *,TCHAR * *)"));
 | 
			
		||||
                    else
 | 
			
		||||
                        if ( _tcscmp(lpszUnDSymbol, _T("_wmainCRTStartup")) == 0 )
 | 
			
		||||
                            _tcscpy(lpszUnDSymbol, _T("wmainCRTStartup()"));
 | 
			
		||||
 | 
			
		||||
		lpszSymbol[0] = _T('\0');
 | 
			
		||||
        lpszSymbol[0] = _T('\0');
 | 
			
		||||
 | 
			
		||||
		// Let's go through the stack, and modify the function prototype, and insert the actual
 | 
			
		||||
		// parameter values from the stack
 | 
			
		||||
		if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == NULL && _tcsstr( lpszUnDSymbol, _T("()") ) == NULL)
 | 
			
		||||
		{
 | 
			
		||||
			ULONG index = 0;
 | 
			
		||||
			for( ; ; index++ )
 | 
			
		||||
			{
 | 
			
		||||
				lpszParamSep = _tcschr( lpszParsed, _T(',') );
 | 
			
		||||
				if ( lpszParamSep == NULL )
 | 
			
		||||
					break;
 | 
			
		||||
        // Let's go through the stack, and modify the function prototype, and insert the actual
 | 
			
		||||
        // parameter values from the stack
 | 
			
		||||
        if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == NULL && _tcsstr( lpszUnDSymbol, _T("()") ) == NULL)
 | 
			
		||||
        {
 | 
			
		||||
            ULONG index = 0;
 | 
			
		||||
            for( ; ; index++ )
 | 
			
		||||
            {
 | 
			
		||||
                lpszParamSep = _tcschr( lpszParsed, _T(',') );
 | 
			
		||||
                if ( lpszParamSep == NULL )
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
				*lpszParamSep = _T('\0');
 | 
			
		||||
                *lpszParamSep = _T('\0');
 | 
			
		||||
 | 
			
		||||
				_tcscat( lpszSymbol, lpszParsed );
 | 
			
		||||
				_stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X,"), *((ULONG*)(stackAddress) + 2 + index) );
 | 
			
		||||
                _tcscat( lpszSymbol, lpszParsed );
 | 
			
		||||
                _stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X,"), *((ULONG*)(stackAddress) + 2 + index) );
 | 
			
		||||
 | 
			
		||||
				lpszParsed = lpszParamSep + 1;
 | 
			
		||||
			}
 | 
			
		||||
                lpszParsed = lpszParamSep + 1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
			lpszParamSep = _tcschr( lpszParsed, _T(')') );
 | 
			
		||||
			if ( lpszParamSep != NULL )
 | 
			
		||||
			{
 | 
			
		||||
				*lpszParamSep = _T('\0');
 | 
			
		||||
            lpszParamSep = _tcschr( lpszParsed, _T(')') );
 | 
			
		||||
            if ( lpszParamSep != NULL )
 | 
			
		||||
            {
 | 
			
		||||
                *lpszParamSep = _T('\0');
 | 
			
		||||
 | 
			
		||||
				_tcscat( lpszSymbol, lpszParsed );
 | 
			
		||||
				_stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X)"), *((ULONG*)(stackAddress) + 2 + index) );
 | 
			
		||||
                _tcscat( lpszSymbol, lpszParsed );
 | 
			
		||||
                _stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X)"), *((ULONG*)(stackAddress) + 2 + index) );
 | 
			
		||||
 | 
			
		||||
				lpszParsed = lpszParamSep + 1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
                lpszParsed = lpszParamSep + 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		_tcscat( lpszSymbol, lpszParsed );
 | 
			
		||||
        _tcscat( lpszSymbol, lpszParsed );
 | 
			
		||||
 | 
			
		||||
		ret = TRUE;
 | 
			
		||||
	} 
 | 
			
		||||
	GlobalFree( pSym );
 | 
			
		||||
        ret = TRUE;
 | 
			
		||||
    } 
 | 
			
		||||
    GlobalFree( pSym );
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get source file name and line number from IP address
 | 
			
		||||
@@ -236,198 +236,198 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L
 | 
			
		||||
//                       "address"
 | 
			
		||||
static BOOL GetSourceInfoFromAddress( UINT address, LPTSTR lpszSourceInfo )
 | 
			
		||||
{
 | 
			
		||||
	BOOL           ret = FALSE;
 | 
			
		||||
	IMAGEHLP_LINE  lineInfo;
 | 
			
		||||
	DWORD          dwDisp;
 | 
			
		||||
	TCHAR          lpszFileName[BUFFERSIZE] = _T("");
 | 
			
		||||
	TCHAR          lpModuleInfo[BUFFERSIZE] = _T("");
 | 
			
		||||
    BOOL           ret = FALSE;
 | 
			
		||||
    IMAGEHLP_LINE  lineInfo;
 | 
			
		||||
    DWORD          dwDisp;
 | 
			
		||||
    TCHAR          lpszFileName[BUFFERSIZE] = _T("");
 | 
			
		||||
    TCHAR          lpModuleInfo[BUFFERSIZE] = _T("");
 | 
			
		||||
 | 
			
		||||
	_tcscpy( lpszSourceInfo, _T("?(?)") );
 | 
			
		||||
    _tcscpy( lpszSourceInfo, _T("?(?)") );
 | 
			
		||||
 | 
			
		||||
	::ZeroMemory( &lineInfo, sizeof( lineInfo ) );
 | 
			
		||||
	lineInfo.SizeOfStruct = sizeof( lineInfo );
 | 
			
		||||
    ::ZeroMemory( &lineInfo, sizeof( lineInfo ) );
 | 
			
		||||
    lineInfo.SizeOfStruct = sizeof( lineInfo );
 | 
			
		||||
 | 
			
		||||
	if ( SymGetLineFromAddr( GetCurrentProcess(), address, &dwDisp, &lineInfo ) )
 | 
			
		||||
	{
 | 
			
		||||
		// Got it. Let's use "sourcefile(linenumber)" format
 | 
			
		||||
		PCSTR2LPTSTR( lineInfo.FileName, lpszFileName );
 | 
			
		||||
		TCHAR fname[_MAX_FNAME];
 | 
			
		||||
		TCHAR ext[_MAX_EXT];
 | 
			
		||||
		_tsplitpath(lpszFileName, NULL, NULL, fname, ext);
 | 
			
		||||
		_stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber );
 | 
			
		||||
		ret = TRUE;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// There is no source file information. :(
 | 
			
		||||
		// Let's use the "modulename!address" format
 | 
			
		||||
		GetModuleNameFromAddress( address, lpModuleInfo );
 | 
			
		||||
    if ( SymGetLineFromAddr( GetCurrentProcess(), address, &dwDisp, &lineInfo ) )
 | 
			
		||||
    {
 | 
			
		||||
        // Got it. Let's use "sourcefile(linenumber)" format
 | 
			
		||||
        PCSTR2LPTSTR( lineInfo.FileName, lpszFileName );
 | 
			
		||||
        TCHAR fname[_MAX_FNAME];
 | 
			
		||||
        TCHAR ext[_MAX_EXT];
 | 
			
		||||
        _tsplitpath(lpszFileName, NULL, NULL, fname, ext);
 | 
			
		||||
        _stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber );
 | 
			
		||||
        ret = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // There is no source file information. :(
 | 
			
		||||
        // Let's use the "modulename!address" format
 | 
			
		||||
        GetModuleNameFromAddress( address, lpModuleInfo );
 | 
			
		||||
 | 
			
		||||
		if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0'))
 | 
			
		||||
			// There is no modulename information. :((
 | 
			
		||||
			// Let's use the "address" format
 | 
			
		||||
			_stprintf( lpszSourceInfo, _T("0x%08X"), address );
 | 
			
		||||
		else
 | 
			
		||||
			_stprintf( lpszSourceInfo, _T("%s!0x%08X"), lpModuleInfo, address );
 | 
			
		||||
        if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0'))
 | 
			
		||||
            // There is no modulename information. :((
 | 
			
		||||
            // Let's use the "address" format
 | 
			
		||||
            _stprintf( lpszSourceInfo, _T("0x%08X"), address );
 | 
			
		||||
        else
 | 
			
		||||
            _stprintf( lpszSourceInfo, _T("%s!0x%08X"), lpModuleInfo, address );
 | 
			
		||||
 | 
			
		||||
		ret = FALSE;
 | 
			
		||||
	}
 | 
			
		||||
        ret = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintFunctionAndSourceInfo(FILE* file, const STACKFRAME& callstack)
 | 
			
		||||
{
 | 
			
		||||
	TCHAR symInfo[BUFFERSIZE] = _T("?");
 | 
			
		||||
	TCHAR srcInfo[BUFFERSIZE] = _T("?");
 | 
			
		||||
    TCHAR symInfo[BUFFERSIZE] = _T("?");
 | 
			
		||||
    TCHAR srcInfo[BUFFERSIZE] = _T("?");
 | 
			
		||||
 | 
			
		||||
	GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo);
 | 
			
		||||
	GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo);
 | 
			
		||||
	etfprint(file, "     " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n");
 | 
			
		||||
    GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo);
 | 
			
		||||
    GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo);
 | 
			
		||||
    etfprint(file, "     " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void StackTrace( HANDLE hThread, const char* lpszMessage, FILE *file )
 | 
			
		||||
{
 | 
			
		||||
	STACKFRAME     callStack;
 | 
			
		||||
	BOOL           bResult;
 | 
			
		||||
	CONTEXT        context;
 | 
			
		||||
	HANDLE         hProcess = GetCurrentProcess();
 | 
			
		||||
    STACKFRAME     callStack;
 | 
			
		||||
    BOOL           bResult;
 | 
			
		||||
    CONTEXT        context;
 | 
			
		||||
    HANDLE         hProcess = GetCurrentProcess();
 | 
			
		||||
 | 
			
		||||
	// If it's not this thread, let's suspend it, and resume it at the end
 | 
			
		||||
	if ( hThread != GetCurrentThread() )
 | 
			
		||||
		if ( SuspendThread( hThread ) == -1 )
 | 
			
		||||
		{
 | 
			
		||||
			// whaaat ?!
 | 
			
		||||
			etfprint(file, "Call stack info failed\n");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
    // If it's not this thread, let's suspend it, and resume it at the end
 | 
			
		||||
    if ( hThread != GetCurrentThread() )
 | 
			
		||||
        if ( SuspendThread( hThread ) == -1 )
 | 
			
		||||
        {
 | 
			
		||||
            // whaaat ?!
 | 
			
		||||
            etfprint(file, "Call stack info failed\n");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		::ZeroMemory( &context, sizeof(context) );
 | 
			
		||||
		context.ContextFlags = CONTEXT_FULL;
 | 
			
		||||
        ::ZeroMemory( &context, sizeof(context) );
 | 
			
		||||
        context.ContextFlags = CONTEXT_FULL;
 | 
			
		||||
 | 
			
		||||
		if ( !GetThreadContext( hThread, &context ) )
 | 
			
		||||
		{
 | 
			
		||||
			etfprint(file, "Call stack info failed\n");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
        if ( !GetThreadContext( hThread, &context ) )
 | 
			
		||||
        {
 | 
			
		||||
            etfprint(file, "Call stack info failed\n");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		::ZeroMemory( &callStack, sizeof(callStack) );
 | 
			
		||||
        ::ZeroMemory( &callStack, sizeof(callStack) );
 | 
			
		||||
#ifndef _M_X64
 | 
			
		||||
		callStack.AddrPC.Offset    = context.Eip;
 | 
			
		||||
		callStack.AddrStack.Offset = context.Esp;
 | 
			
		||||
		callStack.AddrFrame.Offset = context.Ebp;
 | 
			
		||||
        callStack.AddrPC.Offset    = context.Eip;
 | 
			
		||||
        callStack.AddrStack.Offset = context.Esp;
 | 
			
		||||
        callStack.AddrFrame.Offset = context.Ebp;
 | 
			
		||||
#else
 | 
			
		||||
		callStack.AddrPC.Offset    = context.Rip;
 | 
			
		||||
		callStack.AddrStack.Offset = context.Rsp;
 | 
			
		||||
		callStack.AddrFrame.Offset = context.Rbp;
 | 
			
		||||
        callStack.AddrPC.Offset    = context.Rip;
 | 
			
		||||
        callStack.AddrStack.Offset = context.Rsp;
 | 
			
		||||
        callStack.AddrFrame.Offset = context.Rbp;
 | 
			
		||||
#endif
 | 
			
		||||
		callStack.AddrPC.Mode      = AddrModeFlat;
 | 
			
		||||
		callStack.AddrStack.Mode   = AddrModeFlat;
 | 
			
		||||
		callStack.AddrFrame.Mode   = AddrModeFlat;
 | 
			
		||||
        callStack.AddrPC.Mode      = AddrModeFlat;
 | 
			
		||||
        callStack.AddrStack.Mode   = AddrModeFlat;
 | 
			
		||||
        callStack.AddrFrame.Mode   = AddrModeFlat;
 | 
			
		||||
 | 
			
		||||
		etfprint(file, "Call stack info: \n");
 | 
			
		||||
		etfprint(file, lpszMessage);
 | 
			
		||||
        etfprint(file, "Call stack info: \n");
 | 
			
		||||
        etfprint(file, lpszMessage);
 | 
			
		||||
 | 
			
		||||
		PrintFunctionAndSourceInfo(file, callStack);
 | 
			
		||||
        PrintFunctionAndSourceInfo(file, callStack);
 | 
			
		||||
 | 
			
		||||
		for( ULONG index = 0; ; index++ ) 
 | 
			
		||||
		{
 | 
			
		||||
			bResult = StackWalk(
 | 
			
		||||
				IMAGE_FILE_MACHINE_I386,
 | 
			
		||||
				hProcess,
 | 
			
		||||
				hThread,
 | 
			
		||||
				&callStack,
 | 
			
		||||
				NULL, 
 | 
			
		||||
				NULL,
 | 
			
		||||
				SymFunctionTableAccess,
 | 
			
		||||
				SymGetModuleBase,
 | 
			
		||||
				NULL);
 | 
			
		||||
        for( ULONG index = 0; ; index++ ) 
 | 
			
		||||
        {
 | 
			
		||||
            bResult = StackWalk(
 | 
			
		||||
                IMAGE_FILE_MACHINE_I386,
 | 
			
		||||
                hProcess,
 | 
			
		||||
                hThread,
 | 
			
		||||
                &callStack,
 | 
			
		||||
                NULL, 
 | 
			
		||||
                NULL,
 | 
			
		||||
                SymFunctionTableAccess,
 | 
			
		||||
                SymGetModuleBase,
 | 
			
		||||
                NULL);
 | 
			
		||||
 | 
			
		||||
			if ( index == 0 )
 | 
			
		||||
				continue;
 | 
			
		||||
            if ( index == 0 )
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
			if( !bResult || callStack.AddrFrame.Offset == 0 ) 
 | 
			
		||||
				break;
 | 
			
		||||
            if( !bResult || callStack.AddrFrame.Offset == 0 ) 
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
			PrintFunctionAndSourceInfo(file, callStack);
 | 
			
		||||
            PrintFunctionAndSourceInfo(file, callStack);
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		if ( hThread != GetCurrentThread() )
 | 
			
		||||
			ResumeThread( hThread );
 | 
			
		||||
        if ( hThread != GetCurrentThread() )
 | 
			
		||||
            ResumeThread( hThread );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void StackTrace(HANDLE hThread, const char* lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp )
 | 
			
		||||
{
 | 
			
		||||
	STACKFRAME     callStack;
 | 
			
		||||
	BOOL           bResult;
 | 
			
		||||
	TCHAR          symInfo[BUFFERSIZE] = _T("?");
 | 
			
		||||
	TCHAR          srcInfo[BUFFERSIZE] = _T("?");
 | 
			
		||||
	HANDLE         hProcess = GetCurrentProcess();
 | 
			
		||||
    STACKFRAME     callStack;
 | 
			
		||||
    BOOL           bResult;
 | 
			
		||||
    TCHAR          symInfo[BUFFERSIZE] = _T("?");
 | 
			
		||||
    TCHAR          srcInfo[BUFFERSIZE] = _T("?");
 | 
			
		||||
    HANDLE         hProcess = GetCurrentProcess();
 | 
			
		||||
 | 
			
		||||
	// If it's not this thread, let's suspend it, and resume it at the end
 | 
			
		||||
	if ( hThread != GetCurrentThread() )
 | 
			
		||||
		if ( SuspendThread( hThread ) == -1 )
 | 
			
		||||
		{
 | 
			
		||||
			// whaaat ?!
 | 
			
		||||
			etfprint(file, "Call stack info failed\n");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
    // If it's not this thread, let's suspend it, and resume it at the end
 | 
			
		||||
    if ( hThread != GetCurrentThread() )
 | 
			
		||||
        if ( SuspendThread( hThread ) == -1 )
 | 
			
		||||
        {
 | 
			
		||||
            // whaaat ?!
 | 
			
		||||
            etfprint(file, "Call stack info failed\n");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		::ZeroMemory( &callStack, sizeof(callStack) );
 | 
			
		||||
		callStack.AddrPC.Offset    = eip;
 | 
			
		||||
		callStack.AddrStack.Offset = esp;
 | 
			
		||||
		callStack.AddrFrame.Offset = ebp;
 | 
			
		||||
		callStack.AddrPC.Mode      = AddrModeFlat;
 | 
			
		||||
		callStack.AddrStack.Mode   = AddrModeFlat;
 | 
			
		||||
		callStack.AddrFrame.Mode   = AddrModeFlat;
 | 
			
		||||
        ::ZeroMemory( &callStack, sizeof(callStack) );
 | 
			
		||||
        callStack.AddrPC.Offset    = eip;
 | 
			
		||||
        callStack.AddrStack.Offset = esp;
 | 
			
		||||
        callStack.AddrFrame.Offset = ebp;
 | 
			
		||||
        callStack.AddrPC.Mode      = AddrModeFlat;
 | 
			
		||||
        callStack.AddrStack.Mode   = AddrModeFlat;
 | 
			
		||||
        callStack.AddrFrame.Mode   = AddrModeFlat;
 | 
			
		||||
 | 
			
		||||
		etfprint(file, "Call stack info: \n");
 | 
			
		||||
		etfprint(file, lpszMessage);
 | 
			
		||||
        etfprint(file, "Call stack info: \n");
 | 
			
		||||
        etfprint(file, lpszMessage);
 | 
			
		||||
 | 
			
		||||
		PrintFunctionAndSourceInfo(file, callStack);
 | 
			
		||||
        PrintFunctionAndSourceInfo(file, callStack);
 | 
			
		||||
 | 
			
		||||
		for( ULONG index = 0; ; index++ ) 
 | 
			
		||||
		{
 | 
			
		||||
			bResult = StackWalk(
 | 
			
		||||
				IMAGE_FILE_MACHINE_I386,
 | 
			
		||||
				hProcess,
 | 
			
		||||
				hThread,
 | 
			
		||||
				&callStack,
 | 
			
		||||
				NULL, 
 | 
			
		||||
				NULL,
 | 
			
		||||
				SymFunctionTableAccess,
 | 
			
		||||
				SymGetModuleBase,
 | 
			
		||||
				NULL);
 | 
			
		||||
        for( ULONG index = 0; ; index++ ) 
 | 
			
		||||
        {
 | 
			
		||||
            bResult = StackWalk(
 | 
			
		||||
                IMAGE_FILE_MACHINE_I386,
 | 
			
		||||
                hProcess,
 | 
			
		||||
                hThread,
 | 
			
		||||
                &callStack,
 | 
			
		||||
                NULL, 
 | 
			
		||||
                NULL,
 | 
			
		||||
                SymFunctionTableAccess,
 | 
			
		||||
                SymGetModuleBase,
 | 
			
		||||
                NULL);
 | 
			
		||||
 | 
			
		||||
			if ( index == 0 )
 | 
			
		||||
				continue;
 | 
			
		||||
            if ( index == 0 )
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
			if( !bResult || callStack.AddrFrame.Offset == 0 ) 
 | 
			
		||||
				break;
 | 
			
		||||
            if( !bResult || callStack.AddrFrame.Offset == 0 ) 
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
			PrintFunctionAndSourceInfo(file, callStack);
 | 
			
		||||
		}
 | 
			
		||||
            PrintFunctionAndSourceInfo(file, callStack);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		if ( hThread != GetCurrentThread() )
 | 
			
		||||
			ResumeThread( hThread );
 | 
			
		||||
        if ( hThread != GetCurrentThread() )
 | 
			
		||||
            ResumeThread( hThread );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char g_uefbuf[2048];
 | 
			
		||||
 | 
			
		||||
void etfprintf(FILE *file, const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list ap;
 | 
			
		||||
	va_start(ap, format);
 | 
			
		||||
	int len = vsprintf(g_uefbuf, format, ap);
 | 
			
		||||
	fwrite(g_uefbuf, 1, len, file);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
    va_list ap;
 | 
			
		||||
    va_start(ap, format);
 | 
			
		||||
    int len = vsprintf(g_uefbuf, format, ap);
 | 
			
		||||
    fwrite(g_uefbuf, 1, len, file);
 | 
			
		||||
    va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void etfprint(FILE *file, const std::string &text)
 | 
			
		||||
{
 | 
			
		||||
	size_t len = text.length();
 | 
			
		||||
	fwrite(text.data(), 1, len, file);
 | 
			
		||||
    size_t len = text.length();
 | 
			
		||||
    fwrite(text.data(), 1, len, file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif //WIN32
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,9 @@
 | 
			
		||||
 | 
			
		||||
#pragma comment( lib, "imagehlp.lib" )
 | 
			
		||||
 | 
			
		||||
#define EXTENDEDTRACEINITIALIZE( IniSymbolPath )	InitSymInfo( IniSymbolPath )
 | 
			
		||||
#define EXTENDEDTRACEUNINITIALIZE()					UninitSymInfo()
 | 
			
		||||
#define STACKTRACE(file)							StackTrace( GetCurrentThread(), "", file)
 | 
			
		||||
#define EXTENDEDTRACEINITIALIZE( IniSymbolPath )    InitSymInfo( IniSymbolPath )
 | 
			
		||||
#define EXTENDEDTRACEUNINITIALIZE()                    UninitSymInfo()
 | 
			
		||||
#define STACKTRACE(file)                            StackTrace( GetCurrentThread(), "", file)
 | 
			
		||||
#define STACKTRACE2(file, eip, esp, ebp) StackTrace(GetCurrentThread(), "", file, eip, esp, ebp)
 | 
			
		||||
// class File;
 | 
			
		||||
 | 
			
		||||
@@ -41,13 +41,13 @@ void etfprint(FILE *file, const std::string &text);
 | 
			
		||||
#define UEFBUFSIZE 2048
 | 
			
		||||
extern char g_uefbuf[UEFBUFSIZE];
 | 
			
		||||
 | 
			
		||||
#else	// not WIN32
 | 
			
		||||
#else    // not WIN32
 | 
			
		||||
 | 
			
		||||
#define EXTENDEDTRACEINITIALIZE( IniSymbolPath )	((void)0)
 | 
			
		||||
#define EXTENDEDTRACEUNINITIALIZE()					((void)0)
 | 
			
		||||
#define STACKTRACE(file)							((void)0)
 | 
			
		||||
#define STACKTRACE2(file, eip, esp, ebp)			((void)0)
 | 
			
		||||
#define EXTENDEDTRACEINITIALIZE( IniSymbolPath )    ((void)0)
 | 
			
		||||
#define EXTENDEDTRACEUNINITIALIZE()                    ((void)0)
 | 
			
		||||
#define STACKTRACE(file)                            ((void)0)
 | 
			
		||||
#define STACKTRACE2(file, eip, esp, ebp)            ((void)0)
 | 
			
		||||
 | 
			
		||||
#endif	// WIN32
 | 
			
		||||
#endif    // WIN32
 | 
			
		||||
 | 
			
		||||
#endif	// _EXTENDEDTRACE_H_INCLUDED_
 | 
			
		||||
#endif    // _EXTENDEDTRACE_H_INCLUDED_
 | 
			
		||||
 
 | 
			
		||||
@@ -14,100 +14,100 @@ template <typename T>
 | 
			
		||||
class FifoQueue
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	FifoQueue() : m_size(0)
 | 
			
		||||
	{
 | 
			
		||||
		 m_write_ptr = m_read_ptr = new ElementPtr();
 | 
			
		||||
	}
 | 
			
		||||
    FifoQueue() : m_size(0)
 | 
			
		||||
    {
 | 
			
		||||
         m_write_ptr = m_read_ptr = new ElementPtr();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	~FifoQueue()
 | 
			
		||||
	{
 | 
			
		||||
		// this will empty out the whole queue
 | 
			
		||||
		delete m_read_ptr;
 | 
			
		||||
	}
 | 
			
		||||
    ~FifoQueue()
 | 
			
		||||
    {
 | 
			
		||||
        // this will empty out the whole queue
 | 
			
		||||
        delete m_read_ptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	u32 Size() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_size;
 | 
			
		||||
	}
 | 
			
		||||
    u32 Size() const
 | 
			
		||||
    {
 | 
			
		||||
        return m_size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	bool Empty() const
 | 
			
		||||
	{
 | 
			
		||||
		//return (m_read_ptr == m_write_ptr);
 | 
			
		||||
		return (0 == m_size);
 | 
			
		||||
	}
 | 
			
		||||
    bool Empty() const
 | 
			
		||||
    {
 | 
			
		||||
        //return (m_read_ptr == m_write_ptr);
 | 
			
		||||
        return (0 == m_size);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	T& Front() const
 | 
			
		||||
	{
 | 
			
		||||
		return *m_read_ptr->current;
 | 
			
		||||
	}
 | 
			
		||||
    T& Front() const
 | 
			
		||||
    {
 | 
			
		||||
        return *m_read_ptr->current;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	template <typename Arg>
 | 
			
		||||
	void Push(Arg&& t)
 | 
			
		||||
	{
 | 
			
		||||
		// create the element, add it to the queue
 | 
			
		||||
		m_write_ptr->current = new T(std::forward<Arg>(t));
 | 
			
		||||
		// set the next pointer to a new element ptr
 | 
			
		||||
		// then advance the write pointer 
 | 
			
		||||
		m_write_ptr = m_write_ptr->next = new ElementPtr();
 | 
			
		||||
		Common::AtomicIncrement(m_size);
 | 
			
		||||
	}
 | 
			
		||||
    template <typename Arg>
 | 
			
		||||
    void Push(Arg&& t)
 | 
			
		||||
    {
 | 
			
		||||
        // create the element, add it to the queue
 | 
			
		||||
        m_write_ptr->current = new T(std::forward<Arg>(t));
 | 
			
		||||
        // set the next pointer to a new element ptr
 | 
			
		||||
        // then advance the write pointer 
 | 
			
		||||
        m_write_ptr = m_write_ptr->next = new ElementPtr();
 | 
			
		||||
        Common::AtomicIncrement(m_size);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void Pop()
 | 
			
		||||
	{
 | 
			
		||||
		Common::AtomicDecrement(m_size);
 | 
			
		||||
		ElementPtr *const tmpptr = m_read_ptr;
 | 
			
		||||
		// advance the read pointer
 | 
			
		||||
		m_read_ptr = m_read_ptr->next;
 | 
			
		||||
		// set the next element to NULL to stop the recursive deletion
 | 
			
		||||
		tmpptr->next = NULL;
 | 
			
		||||
		delete tmpptr;	// this also deletes the element
 | 
			
		||||
	}
 | 
			
		||||
    void Pop()
 | 
			
		||||
    {
 | 
			
		||||
        Common::AtomicDecrement(m_size);
 | 
			
		||||
        ElementPtr *const tmpptr = m_read_ptr;
 | 
			
		||||
        // advance the read pointer
 | 
			
		||||
        m_read_ptr = m_read_ptr->next;
 | 
			
		||||
        // set the next element to NULL to stop the recursive deletion
 | 
			
		||||
        tmpptr->next = NULL;
 | 
			
		||||
        delete tmpptr;    // this also deletes the element
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	bool Pop(T& t)
 | 
			
		||||
	{
 | 
			
		||||
		if (Empty())
 | 
			
		||||
			return false;
 | 
			
		||||
    bool Pop(T& t)
 | 
			
		||||
    {
 | 
			
		||||
        if (Empty())
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
		t = std::move(Front());
 | 
			
		||||
		Pop();
 | 
			
		||||
        t = std::move(Front());
 | 
			
		||||
        Pop();
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// not thread-safe
 | 
			
		||||
	void Clear()
 | 
			
		||||
	{
 | 
			
		||||
		m_size = 0;
 | 
			
		||||
		delete m_read_ptr;
 | 
			
		||||
		m_write_ptr = m_read_ptr = new ElementPtr();
 | 
			
		||||
	}
 | 
			
		||||
    // not thread-safe
 | 
			
		||||
    void Clear()
 | 
			
		||||
    {
 | 
			
		||||
        m_size = 0;
 | 
			
		||||
        delete m_read_ptr;
 | 
			
		||||
        m_write_ptr = m_read_ptr = new ElementPtr();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	// stores a pointer to element
 | 
			
		||||
	// and a pointer to the next ElementPtr
 | 
			
		||||
	class ElementPtr
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		ElementPtr() : current(NULL), next(NULL) {}
 | 
			
		||||
    // stores a pointer to element
 | 
			
		||||
    // and a pointer to the next ElementPtr
 | 
			
		||||
    class ElementPtr
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        ElementPtr() : current(NULL), next(NULL) {}
 | 
			
		||||
 | 
			
		||||
		~ElementPtr()
 | 
			
		||||
		{
 | 
			
		||||
			if (current)
 | 
			
		||||
			{
 | 
			
		||||
				delete current;
 | 
			
		||||
				// recusion ftw
 | 
			
		||||
				if (next)
 | 
			
		||||
					delete next;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
        ~ElementPtr()
 | 
			
		||||
        {
 | 
			
		||||
            if (current)
 | 
			
		||||
            {
 | 
			
		||||
                delete current;
 | 
			
		||||
                // recusion ftw
 | 
			
		||||
                if (next)
 | 
			
		||||
                    delete next;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		T *volatile current;
 | 
			
		||||
		ElementPtr *volatile next;
 | 
			
		||||
	};
 | 
			
		||||
        T *volatile current;
 | 
			
		||||
        ElementPtr *volatile next;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
	ElementPtr *volatile m_write_ptr;
 | 
			
		||||
	ElementPtr *volatile m_read_ptr;
 | 
			
		||||
	volatile u32 m_size;
 | 
			
		||||
    ElementPtr *volatile m_write_ptr;
 | 
			
		||||
    ElementPtr *volatile m_read_ptr;
 | 
			
		||||
    volatile u32 m_size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,85 +22,85 @@
 | 
			
		||||
 | 
			
		||||
CFileSearch::CFileSearch(const CFileSearch::XStringVector& _rSearchStrings, const CFileSearch::XStringVector& _rDirectories)
 | 
			
		||||
{
 | 
			
		||||
	// Reverse the loop order for speed?
 | 
			
		||||
	for (size_t j = 0; j < _rSearchStrings.size(); j++)
 | 
			
		||||
	{
 | 
			
		||||
		for (size_t i = 0; i < _rDirectories.size(); i++)
 | 
			
		||||
		{
 | 
			
		||||
			FindFiles(_rSearchStrings[j], _rDirectories[i]);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    // Reverse the loop order for speed?
 | 
			
		||||
    for (size_t j = 0; j < _rSearchStrings.size(); j++)
 | 
			
		||||
    {
 | 
			
		||||
        for (size_t i = 0; i < _rDirectories.size(); i++)
 | 
			
		||||
        {
 | 
			
		||||
            FindFiles(_rSearchStrings[j], _rDirectories[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void CFileSearch::FindFiles(const std::string& _searchString, const std::string& _strPath)
 | 
			
		||||
{
 | 
			
		||||
	std::string GCMSearchPath;
 | 
			
		||||
	BuildCompleteFilename(GCMSearchPath, _strPath, _searchString);
 | 
			
		||||
    std::string GCMSearchPath;
 | 
			
		||||
    BuildCompleteFilename(GCMSearchPath, _strPath, _searchString);
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	WIN32_FIND_DATA findData;
 | 
			
		||||
	HANDLE FindFirst = FindFirstFile(UTF8ToTStr(GCMSearchPath).c_str(), &findData);
 | 
			
		||||
    WIN32_FIND_DATA findData;
 | 
			
		||||
    HANDLE FindFirst = FindFirstFile(UTF8ToTStr(GCMSearchPath).c_str(), &findData);
 | 
			
		||||
 | 
			
		||||
	if (FindFirst != INVALID_HANDLE_VALUE)
 | 
			
		||||
	{
 | 
			
		||||
		bool bkeepLooping = true;
 | 
			
		||||
    if (FindFirst != INVALID_HANDLE_VALUE)
 | 
			
		||||
    {
 | 
			
		||||
        bool bkeepLooping = true;
 | 
			
		||||
 | 
			
		||||
		while (bkeepLooping)
 | 
			
		||||
		{			
 | 
			
		||||
			if (findData.cFileName[0] != '.')
 | 
			
		||||
			{
 | 
			
		||||
				std::string strFilename;
 | 
			
		||||
				BuildCompleteFilename(strFilename, _strPath, TStrToUTF8(findData.cFileName));
 | 
			
		||||
				m_FileNames.push_back(strFilename);
 | 
			
		||||
			}
 | 
			
		||||
        while (bkeepLooping)
 | 
			
		||||
        {            
 | 
			
		||||
            if (findData.cFileName[0] != '.')
 | 
			
		||||
            {
 | 
			
		||||
                std::string strFilename;
 | 
			
		||||
                BuildCompleteFilename(strFilename, _strPath, TStrToUTF8(findData.cFileName));
 | 
			
		||||
                m_FileNames.push_back(strFilename);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
			bkeepLooping = FindNextFile(FindFirst, &findData) ? true : false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	FindClose(FindFirst);
 | 
			
		||||
            bkeepLooping = FindNextFile(FindFirst, &findData) ? true : false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    FindClose(FindFirst);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
	// TODO: super lame/broken
 | 
			
		||||
    // TODO: super lame/broken
 | 
			
		||||
 | 
			
		||||
	auto end_match(_searchString);
 | 
			
		||||
    auto end_match(_searchString);
 | 
			
		||||
 | 
			
		||||
	// assuming we have a "*.blah"-like pattern
 | 
			
		||||
	if (!end_match.empty() && end_match[0] == '*')
 | 
			
		||||
		end_match.erase(0, 1);
 | 
			
		||||
    // assuming we have a "*.blah"-like pattern
 | 
			
		||||
    if (!end_match.empty() && end_match[0] == '*')
 | 
			
		||||
        end_match.erase(0, 1);
 | 
			
		||||
 | 
			
		||||
	// ugly
 | 
			
		||||
	if (end_match == ".*")
 | 
			
		||||
		end_match.clear();
 | 
			
		||||
    // ugly
 | 
			
		||||
    if (end_match == ".*")
 | 
			
		||||
        end_match.clear();
 | 
			
		||||
 | 
			
		||||
	DIR* dir = opendir(_strPath.c_str());
 | 
			
		||||
    DIR* dir = opendir(_strPath.c_str());
 | 
			
		||||
 | 
			
		||||
	if (!dir)
 | 
			
		||||
		return;
 | 
			
		||||
    if (!dir)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
	while (auto const dp = readdir(dir))
 | 
			
		||||
	{
 | 
			
		||||
		std::string found(dp->d_name);
 | 
			
		||||
    while (auto const dp = readdir(dir))
 | 
			
		||||
    {
 | 
			
		||||
        std::string found(dp->d_name);
 | 
			
		||||
 | 
			
		||||
		if ((found != ".") && (found != "..")
 | 
			
		||||
			&& (found.size() >= end_match.size())
 | 
			
		||||
			&& std::equal(end_match.rbegin(), end_match.rend(), found.rbegin()))
 | 
			
		||||
		{
 | 
			
		||||
			std::string full_name;
 | 
			
		||||
			if (_strPath.c_str()[_strPath.size()-1] == DIR_SEP_CHR)
 | 
			
		||||
				full_name = _strPath + found;
 | 
			
		||||
			else
 | 
			
		||||
				full_name = _strPath + DIR_SEP + found;
 | 
			
		||||
        if ((found != ".") && (found != "..")
 | 
			
		||||
            && (found.size() >= end_match.size())
 | 
			
		||||
            && std::equal(end_match.rbegin(), end_match.rend(), found.rbegin()))
 | 
			
		||||
        {
 | 
			
		||||
            std::string full_name;
 | 
			
		||||
            if (_strPath.c_str()[_strPath.size()-1] == DIR_SEP_CHR)
 | 
			
		||||
                full_name = _strPath + found;
 | 
			
		||||
            else
 | 
			
		||||
                full_name = _strPath + DIR_SEP + found;
 | 
			
		||||
 | 
			
		||||
			m_FileNames.push_back(full_name);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
            m_FileNames.push_back(full_name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	closedir(dir);
 | 
			
		||||
    closedir(dir);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const CFileSearch::XStringVector& CFileSearch::GetFileNames() const
 | 
			
		||||
{
 | 
			
		||||
	return m_FileNames;
 | 
			
		||||
    return m_FileNames;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,16 +12,16 @@
 | 
			
		||||
class CFileSearch
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	typedef std::vector<std::string>XStringVector;
 | 
			
		||||
    typedef std::vector<std::string>XStringVector;
 | 
			
		||||
 | 
			
		||||
	CFileSearch(const XStringVector& _rSearchStrings, const XStringVector& _rDirectories);
 | 
			
		||||
	const XStringVector& GetFileNames() const;
 | 
			
		||||
    CFileSearch(const XStringVector& _rSearchStrings, const XStringVector& _rDirectories);
 | 
			
		||||
    const XStringVector& GetFileNames() const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	void FindFiles(const std::string& _searchString, const std::string& _strPath);
 | 
			
		||||
    void FindFiles(const std::string& _searchString, const std::string& _strPath);
 | 
			
		||||
 | 
			
		||||
	XStringVector m_FileNames;
 | 
			
		||||
    XStringVector m_FileNames;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _FILESEARCH_H_
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -16,59 +16,59 @@
 | 
			
		||||
template <class T, int N>
 | 
			
		||||
class fixed_size_queue.h
 | 
			
		||||
{
 | 
			
		||||
	T *storage;
 | 
			
		||||
	int head;
 | 
			
		||||
	int tail;
 | 
			
		||||
	int count;  // sacrifice 4 bytes for a simpler implementation. may optimize away in the future.
 | 
			
		||||
    T *storage;
 | 
			
		||||
    int head;
 | 
			
		||||
    int tail;
 | 
			
		||||
    int count;  // sacrifice 4 bytes for a simpler implementation. may optimize away in the future.
 | 
			
		||||
 | 
			
		||||
	// Make copy constructor private for now.
 | 
			
		||||
	fixed_size_queue.h(fixed_size_queue.h &other) {	}
 | 
			
		||||
    // Make copy constructor private for now.
 | 
			
		||||
    fixed_size_queue.h(fixed_size_queue.h &other) {    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	fixed_size_queue.h()
 | 
			
		||||
	{
 | 
			
		||||
		storage = new T[N];
 | 
			
		||||
		clear();
 | 
			
		||||
	}
 | 
			
		||||
    fixed_size_queue.h()
 | 
			
		||||
    {
 | 
			
		||||
        storage = new T[N];
 | 
			
		||||
        clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	~fixed_size_queue.h()
 | 
			
		||||
	{
 | 
			
		||||
		delete [] storage;
 | 
			
		||||
	}
 | 
			
		||||
    ~fixed_size_queue.h()
 | 
			
		||||
    {
 | 
			
		||||
        delete [] storage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void clear() {
 | 
			
		||||
		head = 0;
 | 
			
		||||
		tail = 0;
 | 
			
		||||
		count = 0;
 | 
			
		||||
	}
 | 
			
		||||
    void clear() {
 | 
			
		||||
        head = 0;
 | 
			
		||||
        tail = 0;
 | 
			
		||||
        count = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void push(T t) {
 | 
			
		||||
		storage[tail] = t;
 | 
			
		||||
		tail++;
 | 
			
		||||
		if (tail == N)
 | 
			
		||||
			tail = 0;
 | 
			
		||||
		count++;
 | 
			
		||||
	}
 | 
			
		||||
    void push(T t) {
 | 
			
		||||
        storage[tail] = t;
 | 
			
		||||
        tail++;
 | 
			
		||||
        if (tail == N)
 | 
			
		||||
            tail = 0;
 | 
			
		||||
        count++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void pop() {
 | 
			
		||||
		head++;
 | 
			
		||||
		if (head == N)
 | 
			
		||||
			head = 0;
 | 
			
		||||
		count--;
 | 
			
		||||
	}
 | 
			
		||||
    void pop() {
 | 
			
		||||
        head++;
 | 
			
		||||
        if (head == N)
 | 
			
		||||
            head = 0;
 | 
			
		||||
        count--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	T pop_front() {
 | 
			
		||||
		const T &temp = storage[head];
 | 
			
		||||
		pop();
 | 
			
		||||
		return temp;
 | 
			
		||||
	}
 | 
			
		||||
    T pop_front() {
 | 
			
		||||
        const T &temp = storage[head];
 | 
			
		||||
        pop();
 | 
			
		||||
        return temp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	T &front() { return storage[head]; }
 | 
			
		||||
	const T &front() const { return storage[head]; }
 | 
			
		||||
    T &front() { return storage[head]; }
 | 
			
		||||
    const T &front() const { return storage[head]; }
 | 
			
		||||
 | 
			
		||||
	size_t size() const {
 | 
			
		||||
		return count;
 | 
			
		||||
	}
 | 
			
		||||
    size_t size() const {
 | 
			
		||||
        return count;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _FIXED_SIZE_QUEUE_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -16,29 +16,29 @@ static u64 (*ptrHashFunction)(const u8 *src, int len, u32 samples) = &GetMurmurH
 | 
			
		||||
// Implementation from Wikipedia.
 | 
			
		||||
u32 HashFletcher(const u8* data_u8, size_t length)
 | 
			
		||||
{
 | 
			
		||||
	const u16* data = (const u16*)data_u8; /* Pointer to the data to be summed */
 | 
			
		||||
	size_t len = (length + 1) / 2; /* Length in 16-bit words */
 | 
			
		||||
	u32 sum1 = 0xffff, sum2 = 0xffff;
 | 
			
		||||
    const u16* data = (const u16*)data_u8; /* Pointer to the data to be summed */
 | 
			
		||||
    size_t len = (length + 1) / 2; /* Length in 16-bit words */
 | 
			
		||||
    u32 sum1 = 0xffff, sum2 = 0xffff;
 | 
			
		||||
 | 
			
		||||
	while (len)
 | 
			
		||||
	{
 | 
			
		||||
		size_t tlen = len > 360 ? 360 : len;
 | 
			
		||||
		len -= tlen;
 | 
			
		||||
    while (len)
 | 
			
		||||
    {
 | 
			
		||||
        size_t tlen = len > 360 ? 360 : len;
 | 
			
		||||
        len -= tlen;
 | 
			
		||||
 | 
			
		||||
		do {
 | 
			
		||||
			sum1 += *data++;
 | 
			
		||||
			sum2 += sum1;
 | 
			
		||||
		}
 | 
			
		||||
		while (--tlen);
 | 
			
		||||
        do {
 | 
			
		||||
            sum1 += *data++;
 | 
			
		||||
            sum2 += sum1;
 | 
			
		||||
        }
 | 
			
		||||
        while (--tlen);
 | 
			
		||||
 | 
			
		||||
		sum1 = (sum1 & 0xffff) + (sum1 >> 16);
 | 
			
		||||
		sum2 = (sum2 & 0xffff) + (sum2 >> 16);
 | 
			
		||||
	}
 | 
			
		||||
        sum1 = (sum1 & 0xffff) + (sum1 >> 16);
 | 
			
		||||
        sum2 = (sum2 & 0xffff) + (sum2 >> 16);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// Second reduction step to reduce sums to 16 bits
 | 
			
		||||
	sum1 = (sum1 & 0xffff) + (sum1 >> 16);
 | 
			
		||||
	sum2 = (sum2 & 0xffff) + (sum2 >> 16);
 | 
			
		||||
	return(sum2 << 16 | sum1);
 | 
			
		||||
    // Second reduction step to reduce sums to 16 bits
 | 
			
		||||
    sum1 = (sum1 & 0xffff) + (sum1 >> 16);
 | 
			
		||||
    sum2 = (sum2 & 0xffff) + (sum2 >> 16);
 | 
			
		||||
    return(sum2 << 16 | sum1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -48,54 +48,54 @@ u32 HashFletcher(const u8* data_u8, size_t length)
 | 
			
		||||
// data: Pointer to the data to be summed; len is in bytes
 | 
			
		||||
u32 HashAdler32(const u8* data, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	u32 a = 1, b = 0;
 | 
			
		||||
    u32 a = 1, b = 0;
 | 
			
		||||
 | 
			
		||||
	while (len)
 | 
			
		||||
	{
 | 
			
		||||
		size_t tlen = len > 5550 ? 5550 : len;
 | 
			
		||||
		len -= tlen;
 | 
			
		||||
    while (len)
 | 
			
		||||
    {
 | 
			
		||||
        size_t tlen = len > 5550 ? 5550 : len;
 | 
			
		||||
        len -= tlen;
 | 
			
		||||
 | 
			
		||||
		do
 | 
			
		||||
		{
 | 
			
		||||
			a += *data++;
 | 
			
		||||
			b += a;
 | 
			
		||||
		}
 | 
			
		||||
		while (--tlen);
 | 
			
		||||
        do
 | 
			
		||||
        {
 | 
			
		||||
            a += *data++;
 | 
			
		||||
            b += a;
 | 
			
		||||
        }
 | 
			
		||||
        while (--tlen);
 | 
			
		||||
 | 
			
		||||
		a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER);
 | 
			
		||||
		b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER);
 | 
			
		||||
	}
 | 
			
		||||
        a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER);
 | 
			
		||||
        b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// It can be shown that a <= 0x1013a here, so a single subtract will do.
 | 
			
		||||
	if (a >= MOD_ADLER)
 | 
			
		||||
	{
 | 
			
		||||
		a -= MOD_ADLER;
 | 
			
		||||
	}
 | 
			
		||||
    // It can be shown that a <= 0x1013a here, so a single subtract will do.
 | 
			
		||||
    if (a >= MOD_ADLER)
 | 
			
		||||
    {
 | 
			
		||||
        a -= MOD_ADLER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// It can be shown that b can reach 0xfff87 here.
 | 
			
		||||
	b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER);
 | 
			
		||||
    // It can be shown that b can reach 0xfff87 here.
 | 
			
		||||
    b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER);
 | 
			
		||||
 | 
			
		||||
	if (b >= MOD_ADLER)
 | 
			
		||||
	{
 | 
			
		||||
		b -= MOD_ADLER;
 | 
			
		||||
	}
 | 
			
		||||
    if (b >= MOD_ADLER)
 | 
			
		||||
    {
 | 
			
		||||
        b -= MOD_ADLER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	return((b << 16) | a);
 | 
			
		||||
    return((b << 16) | a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stupid hash - but can't go back now :)
 | 
			
		||||
// Don't use for new things. At least it's reasonably fast.
 | 
			
		||||
u32 HashEctor(const u8* ptr, int length)
 | 
			
		||||
{
 | 
			
		||||
	u32 crc = 0;
 | 
			
		||||
    u32 crc = 0;
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < length; i++)
 | 
			
		||||
	{
 | 
			
		||||
		crc ^= ptr[i];
 | 
			
		||||
		crc = (crc << 3) | (crc >> 29);
 | 
			
		||||
	}
 | 
			
		||||
    for (int i = 0; i < length; i++)
 | 
			
		||||
    {
 | 
			
		||||
        crc ^= ptr[i];
 | 
			
		||||
        crc = (crc << 3) | (crc >> 29);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	return(crc);
 | 
			
		||||
    return(crc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -107,7 +107,7 @@ u32 HashEctor(const u8* ptr, int length)
 | 
			
		||||
 | 
			
		||||
inline u64 getblock(const u64 * p, int i)
 | 
			
		||||
{
 | 
			
		||||
	return p[i];
 | 
			
		||||
    return p[i];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//----------
 | 
			
		||||
@@ -115,25 +115,25 @@ inline u64 getblock(const u64 * p, int i)
 | 
			
		||||
 | 
			
		||||
inline void bmix64(u64 & h1, u64 & h2, u64 & k1, u64 & k2, u64 & c1, u64 & c2)
 | 
			
		||||
{
 | 
			
		||||
	k1 *= c1; 
 | 
			
		||||
	k1  = _rotl64(k1,23); 
 | 
			
		||||
	k1 *= c2;
 | 
			
		||||
	h1 ^= k1;
 | 
			
		||||
	h1 += h2;
 | 
			
		||||
    k1 *= c1; 
 | 
			
		||||
    k1  = _rotl64(k1,23); 
 | 
			
		||||
    k1 *= c2;
 | 
			
		||||
    h1 ^= k1;
 | 
			
		||||
    h1 += h2;
 | 
			
		||||
 | 
			
		||||
	h2 = _rotl64(h2,41);
 | 
			
		||||
    h2 = _rotl64(h2,41);
 | 
			
		||||
 | 
			
		||||
	k2 *= c2; 
 | 
			
		||||
	k2  = _rotl64(k2,23);
 | 
			
		||||
	k2 *= c1;
 | 
			
		||||
	h2 ^= k2;
 | 
			
		||||
	h2 += h1;
 | 
			
		||||
    k2 *= c2; 
 | 
			
		||||
    k2  = _rotl64(k2,23);
 | 
			
		||||
    k2 *= c1;
 | 
			
		||||
    h2 ^= k2;
 | 
			
		||||
    h2 += h1;
 | 
			
		||||
 | 
			
		||||
	h1 = h1*3+0x52dce729;
 | 
			
		||||
	h2 = h2*3+0x38495ab5;
 | 
			
		||||
    h1 = h1*3+0x52dce729;
 | 
			
		||||
    h2 = h2*3+0x38495ab5;
 | 
			
		||||
 | 
			
		||||
	c1 = c1*5+0x7b7d159c;
 | 
			
		||||
	c2 = c2*5+0x6bce6396;
 | 
			
		||||
    c1 = c1*5+0x7b7d159c;
 | 
			
		||||
    c2 = c2*5+0x6bce6396;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//----------
 | 
			
		||||
@@ -141,87 +141,87 @@ inline void bmix64(u64 & h1, u64 & h2, u64 & k1, u64 & k2, u64 & c1, u64 & c2)
 | 
			
		||||
 | 
			
		||||
inline u64 fmix64(u64 k)
 | 
			
		||||
{
 | 
			
		||||
	k ^= k >> 33;
 | 
			
		||||
	k *= 0xff51afd7ed558ccd;
 | 
			
		||||
	k ^= k >> 33;
 | 
			
		||||
	k *= 0xc4ceb9fe1a85ec53;
 | 
			
		||||
	k ^= k >> 33;
 | 
			
		||||
    k ^= k >> 33;
 | 
			
		||||
    k *= 0xff51afd7ed558ccd;
 | 
			
		||||
    k ^= k >> 33;
 | 
			
		||||
    k *= 0xc4ceb9fe1a85ec53;
 | 
			
		||||
    k ^= k >> 33;
 | 
			
		||||
 | 
			
		||||
	return k;
 | 
			
		||||
    return k;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u64 GetMurmurHash3(const u8 *src, int len, u32 samples)
 | 
			
		||||
{
 | 
			
		||||
	const u8 * data = (const u8*)src;
 | 
			
		||||
	const int nblocks = len / 16;
 | 
			
		||||
	u32 Step = (len / 8);
 | 
			
		||||
	if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
	Step = Step / samples;
 | 
			
		||||
	if(Step < 1) Step = 1;
 | 
			
		||||
    const u8 * data = (const u8*)src;
 | 
			
		||||
    const int nblocks = len / 16;
 | 
			
		||||
    u32 Step = (len / 8);
 | 
			
		||||
    if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
    Step = Step / samples;
 | 
			
		||||
    if(Step < 1) Step = 1;
 | 
			
		||||
 | 
			
		||||
	u64 h1 = 0x9368e53c2f6af274;
 | 
			
		||||
	u64 h2 = 0x586dcd208f7cd3fd;
 | 
			
		||||
    u64 h1 = 0x9368e53c2f6af274;
 | 
			
		||||
    u64 h2 = 0x586dcd208f7cd3fd;
 | 
			
		||||
 | 
			
		||||
	u64 c1 = 0x87c37b91114253d5;
 | 
			
		||||
	u64 c2 = 0x4cf5ad432745937f;
 | 
			
		||||
    u64 c1 = 0x87c37b91114253d5;
 | 
			
		||||
    u64 c2 = 0x4cf5ad432745937f;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//----------
 | 
			
		||||
	// body
 | 
			
		||||
    //----------
 | 
			
		||||
    // body
 | 
			
		||||
 | 
			
		||||
	const u64 * blocks = (const u64 *)(data);
 | 
			
		||||
    const u64 * blocks = (const u64 *)(data);
 | 
			
		||||
 | 
			
		||||
	for(int i = 0; i < nblocks; i+=Step)
 | 
			
		||||
	{
 | 
			
		||||
		u64 k1 = getblock(blocks,i*2+0);
 | 
			
		||||
		u64 k2 = getblock(blocks,i*2+1);
 | 
			
		||||
    for(int i = 0; i < nblocks; i+=Step)
 | 
			
		||||
    {
 | 
			
		||||
        u64 k1 = getblock(blocks,i*2+0);
 | 
			
		||||
        u64 k2 = getblock(blocks,i*2+1);
 | 
			
		||||
 | 
			
		||||
		bmix64(h1,h2,k1,k2,c1,c2);
 | 
			
		||||
	}
 | 
			
		||||
        bmix64(h1,h2,k1,k2,c1,c2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	//----------
 | 
			
		||||
	// tail
 | 
			
		||||
    //----------
 | 
			
		||||
    // tail
 | 
			
		||||
 | 
			
		||||
	const u8 * tail = (const u8*)(data + nblocks*16);
 | 
			
		||||
    const u8 * tail = (const u8*)(data + nblocks*16);
 | 
			
		||||
 | 
			
		||||
	u64 k1 = 0;
 | 
			
		||||
	u64 k2 = 0;
 | 
			
		||||
    u64 k1 = 0;
 | 
			
		||||
    u64 k2 = 0;
 | 
			
		||||
 | 
			
		||||
	switch(len & 15)
 | 
			
		||||
	{
 | 
			
		||||
	case 15: k2 ^= u64(tail[14]) << 48;
 | 
			
		||||
	case 14: k2 ^= u64(tail[13]) << 40;
 | 
			
		||||
	case 13: k2 ^= u64(tail[12]) << 32;
 | 
			
		||||
	case 12: k2 ^= u64(tail[11]) << 24;
 | 
			
		||||
	case 11: k2 ^= u64(tail[10]) << 16;
 | 
			
		||||
	case 10: k2 ^= u64(tail[ 9]) << 8;
 | 
			
		||||
	case  9: k2 ^= u64(tail[ 8]) << 0;
 | 
			
		||||
    switch(len & 15)
 | 
			
		||||
    {
 | 
			
		||||
    case 15: k2 ^= u64(tail[14]) << 48;
 | 
			
		||||
    case 14: k2 ^= u64(tail[13]) << 40;
 | 
			
		||||
    case 13: k2 ^= u64(tail[12]) << 32;
 | 
			
		||||
    case 12: k2 ^= u64(tail[11]) << 24;
 | 
			
		||||
    case 11: k2 ^= u64(tail[10]) << 16;
 | 
			
		||||
    case 10: k2 ^= u64(tail[ 9]) << 8;
 | 
			
		||||
    case  9: k2 ^= u64(tail[ 8]) << 0;
 | 
			
		||||
 | 
			
		||||
	case  8: k1 ^= u64(tail[ 7]) << 56;
 | 
			
		||||
	case  7: k1 ^= u64(tail[ 6]) << 48;
 | 
			
		||||
	case  6: k1 ^= u64(tail[ 5]) << 40;
 | 
			
		||||
	case  5: k1 ^= u64(tail[ 4]) << 32;
 | 
			
		||||
	case  4: k1 ^= u64(tail[ 3]) << 24;
 | 
			
		||||
	case  3: k1 ^= u64(tail[ 2]) << 16;
 | 
			
		||||
	case  2: k1 ^= u64(tail[ 1]) << 8;
 | 
			
		||||
	case  1: k1 ^= u64(tail[ 0]) << 0;
 | 
			
		||||
			bmix64(h1,h2,k1,k2,c1,c2);
 | 
			
		||||
	};
 | 
			
		||||
    case  8: k1 ^= u64(tail[ 7]) << 56;
 | 
			
		||||
    case  7: k1 ^= u64(tail[ 6]) << 48;
 | 
			
		||||
    case  6: k1 ^= u64(tail[ 5]) << 40;
 | 
			
		||||
    case  5: k1 ^= u64(tail[ 4]) << 32;
 | 
			
		||||
    case  4: k1 ^= u64(tail[ 3]) << 24;
 | 
			
		||||
    case  3: k1 ^= u64(tail[ 2]) << 16;
 | 
			
		||||
    case  2: k1 ^= u64(tail[ 1]) << 8;
 | 
			
		||||
    case  1: k1 ^= u64(tail[ 0]) << 0;
 | 
			
		||||
            bmix64(h1,h2,k1,k2,c1,c2);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
	//----------
 | 
			
		||||
	// finalization
 | 
			
		||||
    //----------
 | 
			
		||||
    // finalization
 | 
			
		||||
 | 
			
		||||
	h2 ^= len;
 | 
			
		||||
    h2 ^= len;
 | 
			
		||||
 | 
			
		||||
	h1 += h2;
 | 
			
		||||
	h2 += h1;
 | 
			
		||||
    h1 += h2;
 | 
			
		||||
    h2 += h1;
 | 
			
		||||
 | 
			
		||||
	h1 = fmix64(h1);
 | 
			
		||||
	h2 = fmix64(h2);
 | 
			
		||||
    h1 = fmix64(h1);
 | 
			
		||||
    h2 = fmix64(h2);
 | 
			
		||||
 | 
			
		||||
	h1 += h2;
 | 
			
		||||
    h1 += h2;
 | 
			
		||||
 | 
			
		||||
	return h1;
 | 
			
		||||
    return h1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -229,23 +229,23 @@ u64 GetMurmurHash3(const u8 *src, int len, u32 samples)
 | 
			
		||||
u64 GetCRC32(const u8 *src, int len, u32 samples)
 | 
			
		||||
{
 | 
			
		||||
#if _M_SSE >= 0x402
 | 
			
		||||
	u64 h = len;
 | 
			
		||||
	u32 Step = (len / 8);
 | 
			
		||||
	const u64 *data = (const u64 *)src;
 | 
			
		||||
	const u64 *end = data + Step;
 | 
			
		||||
	if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
	Step = Step / samples;
 | 
			
		||||
	if(Step < 1) Step = 1;
 | 
			
		||||
	while(data < end)
 | 
			
		||||
	{
 | 
			
		||||
		h = _mm_crc32_u64(h, data[0]);
 | 
			
		||||
		data += Step;
 | 
			
		||||
	}
 | 
			
		||||
    u64 h = len;
 | 
			
		||||
    u32 Step = (len / 8);
 | 
			
		||||
    const u64 *data = (const u64 *)src;
 | 
			
		||||
    const u64 *end = data + Step;
 | 
			
		||||
    if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
    Step = Step / samples;
 | 
			
		||||
    if(Step < 1) Step = 1;
 | 
			
		||||
    while(data < end)
 | 
			
		||||
    {
 | 
			
		||||
        h = _mm_crc32_u64(h, data[0]);
 | 
			
		||||
        data += Step;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	const u8 *data2 = (const u8*)end;
 | 
			
		||||
	return _mm_crc32_u64(h, u64(data2[0]));
 | 
			
		||||
    const u8 *data2 = (const u8*)end;
 | 
			
		||||
    return _mm_crc32_u64(h, u64(data2[0]));
 | 
			
		||||
#else
 | 
			
		||||
	return 0;
 | 
			
		||||
    return 0;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -259,68 +259,68 @@ u64 GetCRC32(const u8 *src, int len, u32 samples)
 | 
			
		||||
 */
 | 
			
		||||
u64 GetHashHiresTexture(const u8 *src, int len, u32 samples)
 | 
			
		||||
{
 | 
			
		||||
	const u64 m = 0xc6a4a7935bd1e995;
 | 
			
		||||
	u64 h = len * m;
 | 
			
		||||
	const int r = 47;
 | 
			
		||||
	u32 Step = (len / 8);
 | 
			
		||||
	const u64 *data = (const u64 *)src;
 | 
			
		||||
	const u64 *end = data + Step;
 | 
			
		||||
	if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
	Step = Step / samples;
 | 
			
		||||
	if(Step < 1) Step = 1;
 | 
			
		||||
	while(data < end)
 | 
			
		||||
	{
 | 
			
		||||
		u64 k = data[0];
 | 
			
		||||
		data+=Step;
 | 
			
		||||
		k *= m;
 | 
			
		||||
		k ^= k >> r; 
 | 
			
		||||
		k *= m;
 | 
			
		||||
		h ^= k;
 | 
			
		||||
		h *= m;
 | 
			
		||||
	}
 | 
			
		||||
    const u64 m = 0xc6a4a7935bd1e995;
 | 
			
		||||
    u64 h = len * m;
 | 
			
		||||
    const int r = 47;
 | 
			
		||||
    u32 Step = (len / 8);
 | 
			
		||||
    const u64 *data = (const u64 *)src;
 | 
			
		||||
    const u64 *end = data + Step;
 | 
			
		||||
    if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
    Step = Step / samples;
 | 
			
		||||
    if(Step < 1) Step = 1;
 | 
			
		||||
    while(data < end)
 | 
			
		||||
    {
 | 
			
		||||
        u64 k = data[0];
 | 
			
		||||
        data+=Step;
 | 
			
		||||
        k *= m;
 | 
			
		||||
        k ^= k >> r; 
 | 
			
		||||
        k *= m;
 | 
			
		||||
        h ^= k;
 | 
			
		||||
        h *= m;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	const u8 * data2 = (const u8*)end;
 | 
			
		||||
    const u8 * data2 = (const u8*)end;
 | 
			
		||||
 | 
			
		||||
	switch(len & 7)
 | 
			
		||||
	{
 | 
			
		||||
	case 7: h ^= u64(data2[6]) << 48;
 | 
			
		||||
	case 6: h ^= u64(data2[5]) << 40;
 | 
			
		||||
	case 5: h ^= u64(data2[4]) << 32;
 | 
			
		||||
	case 4: h ^= u64(data2[3]) << 24;
 | 
			
		||||
	case 3: h ^= u64(data2[2]) << 16;
 | 
			
		||||
	case 2: h ^= u64(data2[1]) << 8;
 | 
			
		||||
	case 1: h ^= u64(data2[0]);
 | 
			
		||||
			h *= m;
 | 
			
		||||
	};
 | 
			
		||||
    switch(len & 7)
 | 
			
		||||
    {
 | 
			
		||||
    case 7: h ^= u64(data2[6]) << 48;
 | 
			
		||||
    case 6: h ^= u64(data2[5]) << 40;
 | 
			
		||||
    case 5: h ^= u64(data2[4]) << 32;
 | 
			
		||||
    case 4: h ^= u64(data2[3]) << 24;
 | 
			
		||||
    case 3: h ^= u64(data2[2]) << 16;
 | 
			
		||||
    case 2: h ^= u64(data2[1]) << 8;
 | 
			
		||||
    case 1: h ^= u64(data2[0]);
 | 
			
		||||
            h *= m;
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
	h ^= h >> r;
 | 
			
		||||
	h *= m;
 | 
			
		||||
	h ^= h >> r;
 | 
			
		||||
    h ^= h >> r;
 | 
			
		||||
    h *= m;
 | 
			
		||||
    h ^= h >> r;
 | 
			
		||||
 | 
			
		||||
	return h;
 | 
			
		||||
    return h;
 | 
			
		||||
} 
 | 
			
		||||
#else
 | 
			
		||||
// CRC32 hash using the SSE4.2 instruction
 | 
			
		||||
u64 GetCRC32(const u8 *src, int len, u32 samples)
 | 
			
		||||
{
 | 
			
		||||
#if _M_SSE >= 0x402
 | 
			
		||||
	u32 h = len;
 | 
			
		||||
	u32 Step = (len/4);
 | 
			
		||||
	const u32 *data = (const u32 *)src;
 | 
			
		||||
	const u32 *end = data + Step;
 | 
			
		||||
	if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
	Step  = Step / samples;
 | 
			
		||||
	if(Step < 1) Step = 1;
 | 
			
		||||
	while(data < end)
 | 
			
		||||
	{
 | 
			
		||||
		h = _mm_crc32_u32(h, data[0]);
 | 
			
		||||
		data += Step;
 | 
			
		||||
	}
 | 
			
		||||
    u32 h = len;
 | 
			
		||||
    u32 Step = (len/4);
 | 
			
		||||
    const u32 *data = (const u32 *)src;
 | 
			
		||||
    const u32 *end = data + Step;
 | 
			
		||||
    if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
    Step  = Step / samples;
 | 
			
		||||
    if(Step < 1) Step = 1;
 | 
			
		||||
    while(data < end)
 | 
			
		||||
    {
 | 
			
		||||
        h = _mm_crc32_u32(h, data[0]);
 | 
			
		||||
        data += Step;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	const u8 *data2 = (const u8*)end;
 | 
			
		||||
	return (u64)_mm_crc32_u32(h, u32(data2[0]));
 | 
			
		||||
    const u8 *data2 = (const u8*)end;
 | 
			
		||||
    return (u64)_mm_crc32_u32(h, u32(data2[0]));
 | 
			
		||||
#else
 | 
			
		||||
	return 0;
 | 
			
		||||
    return 0;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -330,7 +330,7 @@ u64 GetCRC32(const u8 *src, int len, u32 samples)
 | 
			
		||||
 | 
			
		||||
inline u32 getblock(const u32 * p, int i)
 | 
			
		||||
{
 | 
			
		||||
	return p[i];
 | 
			
		||||
    return p[i];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//----------
 | 
			
		||||
@@ -340,107 +340,107 @@ inline u32 getblock(const u32 * p, int i)
 | 
			
		||||
 | 
			
		||||
inline u32 fmix32(u32 h)
 | 
			
		||||
{
 | 
			
		||||
	h ^= h >> 16;
 | 
			
		||||
	h *= 0x85ebca6b;
 | 
			
		||||
	h ^= h >> 13;
 | 
			
		||||
	h *= 0xc2b2ae35;
 | 
			
		||||
	h ^= h >> 16;
 | 
			
		||||
    h ^= h >> 16;
 | 
			
		||||
    h *= 0x85ebca6b;
 | 
			
		||||
    h ^= h >> 13;
 | 
			
		||||
    h *= 0xc2b2ae35;
 | 
			
		||||
    h ^= h >> 16;
 | 
			
		||||
 | 
			
		||||
	return h;
 | 
			
		||||
    return h;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void bmix32(u32 & h1, u32 & h2, u32 & k1, u32 & k2, u32 & c1, u32 & c2)
 | 
			
		||||
{
 | 
			
		||||
	k1 *= c1; 
 | 
			
		||||
	k1  = _rotl(k1,11); 
 | 
			
		||||
	k1 *= c2;
 | 
			
		||||
	h1 ^= k1;
 | 
			
		||||
	h1 += h2;
 | 
			
		||||
    k1 *= c1; 
 | 
			
		||||
    k1  = _rotl(k1,11); 
 | 
			
		||||
    k1 *= c2;
 | 
			
		||||
    h1 ^= k1;
 | 
			
		||||
    h1 += h2;
 | 
			
		||||
 | 
			
		||||
	h2 = _rotl(h2,17);
 | 
			
		||||
    h2 = _rotl(h2,17);
 | 
			
		||||
 | 
			
		||||
	k2 *= c2; 
 | 
			
		||||
	k2  = _rotl(k2,11);
 | 
			
		||||
	k2 *= c1;
 | 
			
		||||
	h2 ^= k2;
 | 
			
		||||
	h2 += h1;
 | 
			
		||||
    k2 *= c2; 
 | 
			
		||||
    k2  = _rotl(k2,11);
 | 
			
		||||
    k2 *= c1;
 | 
			
		||||
    h2 ^= k2;
 | 
			
		||||
    h2 += h1;
 | 
			
		||||
 | 
			
		||||
	h1 = h1*3+0x52dce729;
 | 
			
		||||
	h2 = h2*3+0x38495ab5;
 | 
			
		||||
    h1 = h1*3+0x52dce729;
 | 
			
		||||
    h2 = h2*3+0x38495ab5;
 | 
			
		||||
 | 
			
		||||
	c1 = c1*5+0x7b7d159c;
 | 
			
		||||
	c2 = c2*5+0x6bce6396;
 | 
			
		||||
    c1 = c1*5+0x7b7d159c;
 | 
			
		||||
    c2 = c2*5+0x6bce6396;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//----------
 | 
			
		||||
 | 
			
		||||
u64 GetMurmurHash3(const u8* src, int len, u32 samples)
 | 
			
		||||
{
 | 
			
		||||
	const u8 * data = (const u8*)src;
 | 
			
		||||
	u32 out[2];
 | 
			
		||||
	const int nblocks = len / 8;
 | 
			
		||||
	u32 Step = (len / 4);
 | 
			
		||||
	if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
	Step = Step / samples;
 | 
			
		||||
	if(Step < 1) Step = 1;
 | 
			
		||||
    const u8 * data = (const u8*)src;
 | 
			
		||||
    u32 out[2];
 | 
			
		||||
    const int nblocks = len / 8;
 | 
			
		||||
    u32 Step = (len / 4);
 | 
			
		||||
    if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
    Step = Step / samples;
 | 
			
		||||
    if(Step < 1) Step = 1;
 | 
			
		||||
 | 
			
		||||
	u32 h1 = 0x8de1c3ac;
 | 
			
		||||
	u32 h2 = 0xbab98226;
 | 
			
		||||
    u32 h1 = 0x8de1c3ac;
 | 
			
		||||
    u32 h2 = 0xbab98226;
 | 
			
		||||
 | 
			
		||||
	u32 c1 = 0x95543787;
 | 
			
		||||
	u32 c2 = 0x2ad7eb25;
 | 
			
		||||
    u32 c1 = 0x95543787;
 | 
			
		||||
    u32 c2 = 0x2ad7eb25;
 | 
			
		||||
 | 
			
		||||
	//----------
 | 
			
		||||
	// body
 | 
			
		||||
    //----------
 | 
			
		||||
    // body
 | 
			
		||||
 | 
			
		||||
	const u32 * blocks = (const u32 *)(data + nblocks*8);
 | 
			
		||||
    const u32 * blocks = (const u32 *)(data + nblocks*8);
 | 
			
		||||
 | 
			
		||||
	for(int i = -nblocks; i < 0; i+=Step)
 | 
			
		||||
	{
 | 
			
		||||
		u32 k1 = getblock(blocks,i*2+0);
 | 
			
		||||
		u32 k2 = getblock(blocks,i*2+1);
 | 
			
		||||
    for(int i = -nblocks; i < 0; i+=Step)
 | 
			
		||||
    {
 | 
			
		||||
        u32 k1 = getblock(blocks,i*2+0);
 | 
			
		||||
        u32 k2 = getblock(blocks,i*2+1);
 | 
			
		||||
 | 
			
		||||
		bmix32(h1,h2,k1,k2,c1,c2);
 | 
			
		||||
	}
 | 
			
		||||
        bmix32(h1,h2,k1,k2,c1,c2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	//----------
 | 
			
		||||
	// tail
 | 
			
		||||
	
 | 
			
		||||
	const u8 * tail = (const u8*)(data + nblocks*8);
 | 
			
		||||
    //----------
 | 
			
		||||
    // tail
 | 
			
		||||
    
 | 
			
		||||
    const u8 * tail = (const u8*)(data + nblocks*8);
 | 
			
		||||
 | 
			
		||||
	u32 k1 = 0;
 | 
			
		||||
	u32 k2 = 0;
 | 
			
		||||
    u32 k1 = 0;
 | 
			
		||||
    u32 k2 = 0;
 | 
			
		||||
 | 
			
		||||
	switch(len & 7)
 | 
			
		||||
	{
 | 
			
		||||
	case 7: k2 ^= tail[6] << 16;
 | 
			
		||||
	case 6: k2 ^= tail[5] << 8;
 | 
			
		||||
	case 5: k2 ^= tail[4] << 0;
 | 
			
		||||
	case 4: k1 ^= tail[3] << 24;
 | 
			
		||||
	case 3: k1 ^= tail[2] << 16;
 | 
			
		||||
	case 2: k1 ^= tail[1] << 8;
 | 
			
		||||
	case 1: k1 ^= tail[0] << 0;
 | 
			
		||||
	        bmix32(h1,h2,k1,k2,c1,c2);
 | 
			
		||||
	};
 | 
			
		||||
    switch(len & 7)
 | 
			
		||||
    {
 | 
			
		||||
    case 7: k2 ^= tail[6] << 16;
 | 
			
		||||
    case 6: k2 ^= tail[5] << 8;
 | 
			
		||||
    case 5: k2 ^= tail[4] << 0;
 | 
			
		||||
    case 4: k1 ^= tail[3] << 24;
 | 
			
		||||
    case 3: k1 ^= tail[2] << 16;
 | 
			
		||||
    case 2: k1 ^= tail[1] << 8;
 | 
			
		||||
    case 1: k1 ^= tail[0] << 0;
 | 
			
		||||
            bmix32(h1,h2,k1,k2,c1,c2);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
	//----------
 | 
			
		||||
	// finalization
 | 
			
		||||
    //----------
 | 
			
		||||
    // finalization
 | 
			
		||||
 | 
			
		||||
	h2 ^= len;
 | 
			
		||||
    h2 ^= len;
 | 
			
		||||
 | 
			
		||||
	h1 += h2;
 | 
			
		||||
	h2 += h1;
 | 
			
		||||
    h1 += h2;
 | 
			
		||||
    h2 += h1;
 | 
			
		||||
 | 
			
		||||
	h1 = fmix32(h1);
 | 
			
		||||
	h2 = fmix32(h2);
 | 
			
		||||
    h1 = fmix32(h1);
 | 
			
		||||
    h2 = fmix32(h2);
 | 
			
		||||
 | 
			
		||||
	h1 += h2;
 | 
			
		||||
	h2 += h1;
 | 
			
		||||
    h1 += h2;
 | 
			
		||||
    h2 += h1;
 | 
			
		||||
 | 
			
		||||
	out[0] = h1;
 | 
			
		||||
	out[1] = h2;
 | 
			
		||||
	
 | 
			
		||||
	return *((u64 *)&out);
 | 
			
		||||
    out[0] = h1;
 | 
			
		||||
    out[1] = h2;
 | 
			
		||||
    
 | 
			
		||||
    return *((u64 *)&out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -450,70 +450,70 @@ u64 GetMurmurHash3(const u8* src, int len, u32 samples)
 | 
			
		||||
 */
 | 
			
		||||
u64 GetHashHiresTexture(const u8 *src, int len, u32 samples)
 | 
			
		||||
{
 | 
			
		||||
	const u64 m = 0xc6a4a7935bd1e995ULL;
 | 
			
		||||
	u64 h = len * m;
 | 
			
		||||
	const int r = 47;
 | 
			
		||||
	u32 Step = (len / 8);
 | 
			
		||||
	const u64 *data = (const u64 *)src;
 | 
			
		||||
	const u64 *end = data + Step;
 | 
			
		||||
	if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
	Step = Step / samples;
 | 
			
		||||
	if(Step < 1) Step = 1;
 | 
			
		||||
	while(data < end)
 | 
			
		||||
	{
 | 
			
		||||
		u64 k = data[0];
 | 
			
		||||
		data+=Step;
 | 
			
		||||
		k *= m; 
 | 
			
		||||
		k ^= k >> r; 
 | 
			
		||||
		k *= m;
 | 
			
		||||
		h ^= k;
 | 
			
		||||
		h *= m; 
 | 
			
		||||
	}
 | 
			
		||||
    const u64 m = 0xc6a4a7935bd1e995ULL;
 | 
			
		||||
    u64 h = len * m;
 | 
			
		||||
    const int r = 47;
 | 
			
		||||
    u32 Step = (len / 8);
 | 
			
		||||
    const u64 *data = (const u64 *)src;
 | 
			
		||||
    const u64 *end = data + Step;
 | 
			
		||||
    if(samples == 0) samples = max(Step, 1u);
 | 
			
		||||
    Step = Step / samples;
 | 
			
		||||
    if(Step < 1) Step = 1;
 | 
			
		||||
    while(data < end)
 | 
			
		||||
    {
 | 
			
		||||
        u64 k = data[0];
 | 
			
		||||
        data+=Step;
 | 
			
		||||
        k *= m; 
 | 
			
		||||
        k ^= k >> r; 
 | 
			
		||||
        k *= m;
 | 
			
		||||
        h ^= k;
 | 
			
		||||
        h *= m; 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	const u8 * data2 = (const u8*)end;
 | 
			
		||||
    const u8 * data2 = (const u8*)end;
 | 
			
		||||
 | 
			
		||||
	switch(len & 7)
 | 
			
		||||
	{
 | 
			
		||||
	case 7: h ^= u64(data2[6]) << 48;
 | 
			
		||||
	case 6: h ^= u64(data2[5]) << 40;
 | 
			
		||||
	case 5: h ^= u64(data2[4]) << 32;
 | 
			
		||||
	case 4: h ^= u64(data2[3]) << 24;
 | 
			
		||||
	case 3: h ^= u64(data2[2]) << 16;
 | 
			
		||||
	case 2: h ^= u64(data2[1]) << 8;
 | 
			
		||||
	case 1: h ^= u64(data2[0]);
 | 
			
		||||
			h *= m;
 | 
			
		||||
	};
 | 
			
		||||
    switch(len & 7)
 | 
			
		||||
    {
 | 
			
		||||
    case 7: h ^= u64(data2[6]) << 48;
 | 
			
		||||
    case 6: h ^= u64(data2[5]) << 40;
 | 
			
		||||
    case 5: h ^= u64(data2[4]) << 32;
 | 
			
		||||
    case 4: h ^= u64(data2[3]) << 24;
 | 
			
		||||
    case 3: h ^= u64(data2[2]) << 16;
 | 
			
		||||
    case 2: h ^= u64(data2[1]) << 8;
 | 
			
		||||
    case 1: h ^= u64(data2[0]);
 | 
			
		||||
            h *= m;
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
	h ^= h >> r;
 | 
			
		||||
	h *= m;
 | 
			
		||||
	h ^= h >> r;
 | 
			
		||||
    h ^= h >> r;
 | 
			
		||||
    h *= m;
 | 
			
		||||
    h ^= h >> r;
 | 
			
		||||
 | 
			
		||||
	return h;
 | 
			
		||||
    return h;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
u64 GetHash64(const u8 *src, int len, u32 samples)
 | 
			
		||||
{
 | 
			
		||||
	return ptrHashFunction(src, len, samples);
 | 
			
		||||
    return ptrHashFunction(src, len, samples);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// sets the hash function used for the texture cache
 | 
			
		||||
void SetHash64Function(bool useHiresTextures)
 | 
			
		||||
{
 | 
			
		||||
	if (useHiresTextures)
 | 
			
		||||
	{
 | 
			
		||||
		ptrHashFunction = &GetHashHiresTexture;
 | 
			
		||||
	}
 | 
			
		||||
    if (useHiresTextures)
 | 
			
		||||
    {
 | 
			
		||||
        ptrHashFunction = &GetHashHiresTexture;
 | 
			
		||||
    }
 | 
			
		||||
#if _M_SSE >= 0x402
 | 
			
		||||
	else if (cpu_info.bSSE4_2 && !useHiresTextures) // sse crc32 version
 | 
			
		||||
	{
 | 
			
		||||
		ptrHashFunction = &GetCRC32;
 | 
			
		||||
	}
 | 
			
		||||
    else if (cpu_info.bSSE4_2 && !useHiresTextures) // sse crc32 version
 | 
			
		||||
    {
 | 
			
		||||
        ptrHashFunction = &GetCRC32;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		ptrHashFunction = &GetMurmurHash3;
 | 
			
		||||
	}
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        ptrHashFunction = &GetMurmurHash3;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ template <typename K, typename V>
 | 
			
		||||
class LinearDiskCacheReader
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	virtual void Read(const K &key, const V *value, u32 value_size) = 0;
 | 
			
		||||
    virtual void Read(const K &key, const V *value, u32 value_size) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Dead simple unsorted key-value store with append functionality.
 | 
			
		||||
@@ -49,143 +49,143 @@ template <typename K, typename V>
 | 
			
		||||
class LinearDiskCache
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	// return number of read entries
 | 
			
		||||
	u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader)
 | 
			
		||||
	{
 | 
			
		||||
		using std::ios_base;
 | 
			
		||||
    // return number of read entries
 | 
			
		||||
    u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader)
 | 
			
		||||
    {
 | 
			
		||||
        using std::ios_base;
 | 
			
		||||
 | 
			
		||||
		// close any currently opened file
 | 
			
		||||
		Close();
 | 
			
		||||
		m_num_entries = 0;
 | 
			
		||||
        // close any currently opened file
 | 
			
		||||
        Close();
 | 
			
		||||
        m_num_entries = 0;
 | 
			
		||||
 | 
			
		||||
		// try opening for reading/writing
 | 
			
		||||
		OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary);
 | 
			
		||||
        // try opening for reading/writing
 | 
			
		||||
        OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary);
 | 
			
		||||
 | 
			
		||||
		m_file.seekg(0, std::ios::end);
 | 
			
		||||
		std::fstream::pos_type end_pos = m_file.tellg();
 | 
			
		||||
		m_file.seekg(0, std::ios::beg);
 | 
			
		||||
		std::fstream::pos_type start_pos = m_file.tellg();
 | 
			
		||||
		std::streamoff file_size = end_pos - start_pos;
 | 
			
		||||
		
 | 
			
		||||
		if (m_file.is_open() && ValidateHeader())
 | 
			
		||||
		{
 | 
			
		||||
			// good header, read some key/value pairs
 | 
			
		||||
			K key;
 | 
			
		||||
        m_file.seekg(0, std::ios::end);
 | 
			
		||||
        std::fstream::pos_type end_pos = m_file.tellg();
 | 
			
		||||
        m_file.seekg(0, std::ios::beg);
 | 
			
		||||
        std::fstream::pos_type start_pos = m_file.tellg();
 | 
			
		||||
        std::streamoff file_size = end_pos - start_pos;
 | 
			
		||||
        
 | 
			
		||||
        if (m_file.is_open() && ValidateHeader())
 | 
			
		||||
        {
 | 
			
		||||
            // good header, read some key/value pairs
 | 
			
		||||
            K key;
 | 
			
		||||
 | 
			
		||||
			V *value = NULL;
 | 
			
		||||
			u32 value_size;
 | 
			
		||||
			u32 entry_number;
 | 
			
		||||
            V *value = NULL;
 | 
			
		||||
            u32 value_size;
 | 
			
		||||
            u32 entry_number;
 | 
			
		||||
 | 
			
		||||
			std::fstream::pos_type last_pos = m_file.tellg();
 | 
			
		||||
            std::fstream::pos_type last_pos = m_file.tellg();
 | 
			
		||||
 | 
			
		||||
			while (Read(&value_size))
 | 
			
		||||
			{
 | 
			
		||||
				std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size;
 | 
			
		||||
				if (next_extent > file_size)
 | 
			
		||||
					break;
 | 
			
		||||
            while (Read(&value_size))
 | 
			
		||||
            {
 | 
			
		||||
                std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size;
 | 
			
		||||
                if (next_extent > file_size)
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
				delete[] value;
 | 
			
		||||
				value = new V[value_size];
 | 
			
		||||
                delete[] value;
 | 
			
		||||
                value = new V[value_size];
 | 
			
		||||
 | 
			
		||||
				// read key/value and pass to reader
 | 
			
		||||
				if (Read(&key) &&
 | 
			
		||||
					Read(value, value_size) && 
 | 
			
		||||
					Read(&entry_number) &&
 | 
			
		||||
					entry_number == m_num_entries+1)
 | 
			
		||||
 				{
 | 
			
		||||
					reader.Read(key, value, value_size);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
                // read key/value and pass to reader
 | 
			
		||||
                if (Read(&key) &&
 | 
			
		||||
                    Read(value, value_size) && 
 | 
			
		||||
                    Read(&entry_number) &&
 | 
			
		||||
                    entry_number == m_num_entries+1)
 | 
			
		||||
                 {
 | 
			
		||||
                    reader.Read(key, value, value_size);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
				m_num_entries++;
 | 
			
		||||
				last_pos = m_file.tellg();
 | 
			
		||||
			}
 | 
			
		||||
			m_file.seekp(last_pos);
 | 
			
		||||
			m_file.clear();
 | 
			
		||||
                m_num_entries++;
 | 
			
		||||
                last_pos = m_file.tellg();
 | 
			
		||||
            }
 | 
			
		||||
            m_file.seekp(last_pos);
 | 
			
		||||
            m_file.clear();
 | 
			
		||||
 | 
			
		||||
			delete[] value;
 | 
			
		||||
			return m_num_entries;
 | 
			
		||||
		}
 | 
			
		||||
            delete[] value;
 | 
			
		||||
            return m_num_entries;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		// failed to open file for reading or bad header
 | 
			
		||||
		// close and recreate file
 | 
			
		||||
		Close();
 | 
			
		||||
		m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary);
 | 
			
		||||
		WriteHeader();
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	void Sync()
 | 
			
		||||
	{
 | 
			
		||||
		m_file.flush();
 | 
			
		||||
	}
 | 
			
		||||
        // failed to open file for reading or bad header
 | 
			
		||||
        // close and recreate file
 | 
			
		||||
        Close();
 | 
			
		||||
        m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary);
 | 
			
		||||
        WriteHeader();
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void Sync()
 | 
			
		||||
    {
 | 
			
		||||
        m_file.flush();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void Close()
 | 
			
		||||
	{
 | 
			
		||||
		if (m_file.is_open())
 | 
			
		||||
			m_file.close();
 | 
			
		||||
		// clear any error flags
 | 
			
		||||
		m_file.clear();
 | 
			
		||||
	}
 | 
			
		||||
    void Close()
 | 
			
		||||
    {
 | 
			
		||||
        if (m_file.is_open())
 | 
			
		||||
            m_file.close();
 | 
			
		||||
        // clear any error flags
 | 
			
		||||
        m_file.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// Appends a key-value pair to the store.
 | 
			
		||||
	void Append(const K &key, const V *value, u32 value_size)
 | 
			
		||||
	{
 | 
			
		||||
		// TODO: Should do a check that we don't already have "key"? (I think each caller does that already.)
 | 
			
		||||
		Write(&value_size);
 | 
			
		||||
		Write(&key);
 | 
			
		||||
		Write(value, value_size);
 | 
			
		||||
		m_num_entries++;
 | 
			
		||||
		Write(&m_num_entries);
 | 
			
		||||
	}
 | 
			
		||||
    // Appends a key-value pair to the store.
 | 
			
		||||
    void Append(const K &key, const V *value, u32 value_size)
 | 
			
		||||
    {
 | 
			
		||||
        // TODO: Should do a check that we don't already have "key"? (I think each caller does that already.)
 | 
			
		||||
        Write(&value_size);
 | 
			
		||||
        Write(&key);
 | 
			
		||||
        Write(value, value_size);
 | 
			
		||||
        m_num_entries++;
 | 
			
		||||
        Write(&m_num_entries);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void WriteHeader()
 | 
			
		||||
	{
 | 
			
		||||
		Write(&m_header);
 | 
			
		||||
	}
 | 
			
		||||
    void WriteHeader()
 | 
			
		||||
    {
 | 
			
		||||
        Write(&m_header);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	bool ValidateHeader()
 | 
			
		||||
	{
 | 
			
		||||
		char file_header[sizeof(Header)];
 | 
			
		||||
    bool ValidateHeader()
 | 
			
		||||
    {
 | 
			
		||||
        char file_header[sizeof(Header)];
 | 
			
		||||
 | 
			
		||||
		return (Read(file_header, sizeof(Header))
 | 
			
		||||
			&& !memcmp((const char*)&m_header, file_header, sizeof(Header)));
 | 
			
		||||
	}
 | 
			
		||||
        return (Read(file_header, sizeof(Header))
 | 
			
		||||
            && !memcmp((const char*)&m_header, file_header, sizeof(Header)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	template <typename D>
 | 
			
		||||
	bool Write(const D *data, u32 count = 1)
 | 
			
		||||
	{
 | 
			
		||||
		return m_file.write((const char*)data, count * sizeof(D)).good();
 | 
			
		||||
	}
 | 
			
		||||
    template <typename D>
 | 
			
		||||
    bool Write(const D *data, u32 count = 1)
 | 
			
		||||
    {
 | 
			
		||||
        return m_file.write((const char*)data, count * sizeof(D)).good();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	template <typename D>
 | 
			
		||||
	bool Read(const D *data, u32 count = 1)
 | 
			
		||||
	{
 | 
			
		||||
		return m_file.read((char*)data, count * sizeof(D)).good();
 | 
			
		||||
	}
 | 
			
		||||
    template <typename D>
 | 
			
		||||
    bool Read(const D *data, u32 count = 1)
 | 
			
		||||
    {
 | 
			
		||||
        return m_file.read((char*)data, count * sizeof(D)).good();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	struct Header
 | 
			
		||||
	{
 | 
			
		||||
		Header()
 | 
			
		||||
			: id(*(u32*)"DCAC")
 | 
			
		||||
			, key_t_size(sizeof(K))
 | 
			
		||||
			, value_t_size(sizeof(V))
 | 
			
		||||
		{
 | 
			
		||||
			memcpy(ver, scm_rev_git_str, 40);
 | 
			
		||||
		}
 | 
			
		||||
    struct Header
 | 
			
		||||
    {
 | 
			
		||||
        Header()
 | 
			
		||||
            : id(*(u32*)"DCAC")
 | 
			
		||||
            , key_t_size(sizeof(K))
 | 
			
		||||
            , value_t_size(sizeof(V))
 | 
			
		||||
        {
 | 
			
		||||
            memcpy(ver, scm_rev_git_str, 40);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		const u32 id;
 | 
			
		||||
		const u16 key_t_size, value_t_size;
 | 
			
		||||
		char ver[40];
 | 
			
		||||
        const u32 id;
 | 
			
		||||
        const u16 key_t_size, value_t_size;
 | 
			
		||||
        char ver[40];
 | 
			
		||||
 | 
			
		||||
	} m_header;
 | 
			
		||||
    } m_header;
 | 
			
		||||
 | 
			
		||||
	std::fstream m_file;
 | 
			
		||||
	u32 m_num_entries;
 | 
			
		||||
    std::fstream m_file;
 | 
			
		||||
    u32 m_num_entries;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif  // _LINEAR_DISKCACHE
 | 
			
		||||
 
 | 
			
		||||
@@ -5,74 +5,74 @@
 | 
			
		||||
#ifndef _LOG_H_
 | 
			
		||||
#define _LOG_H_
 | 
			
		||||
 | 
			
		||||
#define	NOTICE_LEVEL  1  // VERY important information that is NOT errors. Like startup and OSReports.
 | 
			
		||||
#define	ERROR_LEVEL   2  // Critical errors 
 | 
			
		||||
#define	WARNING_LEVEL 3  // Something is suspicious.
 | 
			
		||||
#define	INFO_LEVEL    4  // General information.
 | 
			
		||||
#define	DEBUG_LEVEL   5  // Detailed debugging - might make things slow.
 | 
			
		||||
#define    NOTICE_LEVEL  1  // VERY important information that is NOT errors. Like startup and OSReports.
 | 
			
		||||
#define    ERROR_LEVEL   2  // Critical errors 
 | 
			
		||||
#define    WARNING_LEVEL 3  // Something is suspicious.
 | 
			
		||||
#define    INFO_LEVEL    4  // General information.
 | 
			
		||||
#define    DEBUG_LEVEL   5  // Detailed debugging - might make things slow.
 | 
			
		||||
 | 
			
		||||
namespace LogTypes
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
enum LOG_TYPE {
 | 
			
		||||
	ACTIONREPLAY,
 | 
			
		||||
	AUDIO,
 | 
			
		||||
	AUDIO_INTERFACE,
 | 
			
		||||
	BOOT,
 | 
			
		||||
	COMMANDPROCESSOR,
 | 
			
		||||
	COMMON,
 | 
			
		||||
	CONSOLE,
 | 
			
		||||
	DISCIO,
 | 
			
		||||
	FILEMON,
 | 
			
		||||
	DSPHLE,
 | 
			
		||||
	DSPLLE,
 | 
			
		||||
	DSP_MAIL,
 | 
			
		||||
	DSPINTERFACE,
 | 
			
		||||
	DVDINTERFACE,
 | 
			
		||||
	DYNA_REC,
 | 
			
		||||
	EXPANSIONINTERFACE,
 | 
			
		||||
	GDB_STUB,
 | 
			
		||||
	ARM11,
 | 
			
		||||
	GPFIFO,
 | 
			
		||||
	OSHLE,
 | 
			
		||||
	MASTER_LOG,
 | 
			
		||||
	MEMMAP,
 | 
			
		||||
	MEMCARD_MANAGER,
 | 
			
		||||
	OSREPORT,
 | 
			
		||||
	PAD, 
 | 
			
		||||
	PROCESSORINTERFACE,
 | 
			
		||||
	PIXELENGINE,
 | 
			
		||||
	SERIALINTERFACE,
 | 
			
		||||
	SP1,
 | 
			
		||||
	STREAMINGINTERFACE,
 | 
			
		||||
	VIDEO,
 | 
			
		||||
	VIDEOINTERFACE,
 | 
			
		||||
	LOADER,
 | 
			
		||||
	FILESYS,
 | 
			
		||||
	WII_IPC_DVD,
 | 
			
		||||
	WII_IPC_ES,
 | 
			
		||||
	WII_IPC_FILEIO,
 | 
			
		||||
	WII_IPC_HID,
 | 
			
		||||
	WII_IPC_HLE,
 | 
			
		||||
	WII_IPC_NET,
 | 
			
		||||
	WII_IPC_WC24,
 | 
			
		||||
	WII_IPC_SSL,
 | 
			
		||||
	WII_IPC_SD,
 | 
			
		||||
	WII_IPC_STM,
 | 
			
		||||
	WII_IPC_WIIMOTE,
 | 
			
		||||
	TIME,
 | 
			
		||||
	NETPLAY,
 | 
			
		||||
    ACTIONREPLAY,
 | 
			
		||||
    AUDIO,
 | 
			
		||||
    AUDIO_INTERFACE,
 | 
			
		||||
    BOOT,
 | 
			
		||||
    COMMANDPROCESSOR,
 | 
			
		||||
    COMMON,
 | 
			
		||||
    CONSOLE,
 | 
			
		||||
    DISCIO,
 | 
			
		||||
    FILEMON,
 | 
			
		||||
    DSPHLE,
 | 
			
		||||
    DSPLLE,
 | 
			
		||||
    DSP_MAIL,
 | 
			
		||||
    DSPINTERFACE,
 | 
			
		||||
    DVDINTERFACE,
 | 
			
		||||
    DYNA_REC,
 | 
			
		||||
    EXPANSIONINTERFACE,
 | 
			
		||||
    GDB_STUB,
 | 
			
		||||
    ARM11,
 | 
			
		||||
    GPFIFO,
 | 
			
		||||
    OSHLE,
 | 
			
		||||
    MASTER_LOG,
 | 
			
		||||
    MEMMAP,
 | 
			
		||||
    MEMCARD_MANAGER,
 | 
			
		||||
    OSREPORT,
 | 
			
		||||
    PAD, 
 | 
			
		||||
    PROCESSORINTERFACE,
 | 
			
		||||
    PIXELENGINE,
 | 
			
		||||
    SERIALINTERFACE,
 | 
			
		||||
    SP1,
 | 
			
		||||
    STREAMINGINTERFACE,
 | 
			
		||||
    VIDEO,
 | 
			
		||||
    VIDEOINTERFACE,
 | 
			
		||||
    LOADER,
 | 
			
		||||
    FILESYS,
 | 
			
		||||
    WII_IPC_DVD,
 | 
			
		||||
    WII_IPC_ES,
 | 
			
		||||
    WII_IPC_FILEIO,
 | 
			
		||||
    WII_IPC_HID,
 | 
			
		||||
    WII_IPC_HLE,
 | 
			
		||||
    WII_IPC_NET,
 | 
			
		||||
    WII_IPC_WC24,
 | 
			
		||||
    WII_IPC_SSL,
 | 
			
		||||
    WII_IPC_SD,
 | 
			
		||||
    WII_IPC_STM,
 | 
			
		||||
    WII_IPC_WIIMOTE,
 | 
			
		||||
    TIME,
 | 
			
		||||
    NETPLAY,
 | 
			
		||||
 | 
			
		||||
	NUMBER_OF_LOGS // Must be last
 | 
			
		||||
    NUMBER_OF_LOGS // Must be last
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// FIXME: should this be removed?
 | 
			
		||||
enum LOG_LEVELS {
 | 
			
		||||
	LNOTICE = NOTICE_LEVEL,
 | 
			
		||||
	LERROR = ERROR_LEVEL,
 | 
			
		||||
	LWARNING = WARNING_LEVEL,
 | 
			
		||||
	LINFO = INFO_LEVEL,
 | 
			
		||||
	LDEBUG = DEBUG_LEVEL,
 | 
			
		||||
    LNOTICE = NOTICE_LEVEL,
 | 
			
		||||
    LERROR = ERROR_LEVEL,
 | 
			
		||||
    LWARNING = WARNING_LEVEL,
 | 
			
		||||
    LINFO = INFO_LEVEL,
 | 
			
		||||
    LDEBUG = DEBUG_LEVEL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define LOGTYPES_LEVELS LogTypes::LOG_LEVELS
 | 
			
		||||
@@ -81,11 +81,11 @@ enum LOG_LEVELS {
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type,
 | 
			
		||||
		const char *file, int line, const char *fmt, ...)
 | 
			
		||||
        const char *file, int line, const char *fmt, ...)
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
		__attribute__((format(printf, 5, 6)))
 | 
			
		||||
        __attribute__((format(printf, 5, 6)))
 | 
			
		||||
#endif
 | 
			
		||||
		;
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
#if defined LOGGING || defined _DEBUG || defined DEBUGFAST
 | 
			
		||||
#define MAX_LOGLEVEL DEBUG_LEVEL
 | 
			
		||||
@@ -100,9 +100,9 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type,
 | 
			
		||||
#else
 | 
			
		||||
// Let the compiler optimize this out
 | 
			
		||||
#define GENERIC_LOG(t, v, ...) { \
 | 
			
		||||
	if (v <= MAX_LOGLEVEL) \
 | 
			
		||||
		GenericLog(v, t, __FILE__, __LINE__, __VA_ARGS__); \
 | 
			
		||||
	}
 | 
			
		||||
    if (v <= MAX_LOGLEVEL) \
 | 
			
		||||
        GenericLog(v, t, __FILE__, __LINE__, __VA_ARGS__); \
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define ERROR_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LERROR, __VA_ARGS__) } while (0)
 | 
			
		||||
@@ -113,16 +113,16 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type,
 | 
			
		||||
 | 
			
		||||
#if MAX_LOGLEVEL >= DEBUG_LEVEL
 | 
			
		||||
#define _dbg_assert_(_t_, _a_) \
 | 
			
		||||
	if (!(_a_)) {\
 | 
			
		||||
		ERROR_LOG(_t_, "Error...\n\n  Line: %d\n  File: %s\n  Time: %s\n\nIgnore and continue?", \
 | 
			
		||||
					   __LINE__, __FILE__, __TIME__); \
 | 
			
		||||
		if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \
 | 
			
		||||
	}
 | 
			
		||||
    if (!(_a_)) {\
 | 
			
		||||
        ERROR_LOG(_t_, "Error...\n\n  Line: %d\n  File: %s\n  Time: %s\n\nIgnore and continue?", \
 | 
			
		||||
                       __LINE__, __FILE__, __TIME__); \
 | 
			
		||||
        if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \
 | 
			
		||||
    }
 | 
			
		||||
#define _dbg_assert_msg_(_t_, _a_, ...)\
 | 
			
		||||
	if (!(_a_)) {\
 | 
			
		||||
		ERROR_LOG(_t_, __VA_ARGS__); \
 | 
			
		||||
		if (!PanicYesNo(__VA_ARGS__)) {Crash();} \
 | 
			
		||||
	}
 | 
			
		||||
    if (!(_a_)) {\
 | 
			
		||||
        ERROR_LOG(_t_, __VA_ARGS__); \
 | 
			
		||||
        if (!PanicYesNo(__VA_ARGS__)) {Crash();} \
 | 
			
		||||
    }
 | 
			
		||||
#define _dbg_update_() Host_UpdateLogDisplay();
 | 
			
		||||
 | 
			
		||||
#else // not debug
 | 
			
		||||
@@ -138,15 +138,15 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type,
 | 
			
		||||
 | 
			
		||||
#ifndef GEKKO
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#define _assert_msg_(_t_, _a_, _fmt_, ...)		\
 | 
			
		||||
	if (!(_a_)) {\
 | 
			
		||||
		if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \
 | 
			
		||||
	}
 | 
			
		||||
#define _assert_msg_(_t_, _a_, _fmt_, ...)        \
 | 
			
		||||
    if (!(_a_)) {\
 | 
			
		||||
        if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \
 | 
			
		||||
    }
 | 
			
		||||
#else // not win32
 | 
			
		||||
#define _assert_msg_(_t_, _a_, _fmt_, ...)		\
 | 
			
		||||
	if (!(_a_)) {\
 | 
			
		||||
		if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \
 | 
			
		||||
	}
 | 
			
		||||
#define _assert_msg_(_t_, _a_, _fmt_, ...)        \
 | 
			
		||||
    if (!(_a_)) {\
 | 
			
		||||
        if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \
 | 
			
		||||
    }
 | 
			
		||||
#endif // WIN32
 | 
			
		||||
#else // GEKKO
 | 
			
		||||
#define _assert_msg_(_t_, _a_, _fmt_, ...)
 | 
			
		||||
 
 | 
			
		||||
@@ -14,187 +14,187 @@
 | 
			
		||||
#include "file_util.h"
 | 
			
		||||
 | 
			
		||||
void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, 
 | 
			
		||||
		const char *file, int line, const char* fmt, ...)
 | 
			
		||||
        const char *file, int line, const char* fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list args;
 | 
			
		||||
	va_start(args, fmt);
 | 
			
		||||
	if (LogManager::GetInstance())
 | 
			
		||||
		LogManager::GetInstance()->Log(level, type,
 | 
			
		||||
			file, line, fmt, args);
 | 
			
		||||
	va_end(args);
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start(args, fmt);
 | 
			
		||||
    if (LogManager::GetInstance())
 | 
			
		||||
        LogManager::GetInstance()->Log(level, type,
 | 
			
		||||
            file, line, fmt, args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LogManager *LogManager::m_logManager = NULL;
 | 
			
		||||
 | 
			
		||||
LogManager::LogManager()
 | 
			
		||||
{
 | 
			
		||||
	// create log files
 | 
			
		||||
	m_Log[LogTypes::MASTER_LOG]			= new LogContainer("*",				"Master Log");
 | 
			
		||||
	m_Log[LogTypes::BOOT]				= new LogContainer("BOOT",			"Boot");
 | 
			
		||||
	m_Log[LogTypes::COMMON]				= new LogContainer("COMMON",		"Common");
 | 
			
		||||
	m_Log[LogTypes::DISCIO]				= new LogContainer("DIO",			"Disc IO");
 | 
			
		||||
	m_Log[LogTypes::FILEMON]			= new LogContainer("FileMon",		"File Monitor");
 | 
			
		||||
	m_Log[LogTypes::PAD]				= new LogContainer("PAD",			"Pad");
 | 
			
		||||
	m_Log[LogTypes::PIXELENGINE]		= new LogContainer("PE",			"PixelEngine");
 | 
			
		||||
	m_Log[LogTypes::COMMANDPROCESSOR]	= new LogContainer("CP",			"CommandProc");
 | 
			
		||||
	m_Log[LogTypes::VIDEOINTERFACE]		= new LogContainer("VI",			"VideoInt");
 | 
			
		||||
	m_Log[LogTypes::SERIALINTERFACE]	= new LogContainer("SI",			"SerialInt");
 | 
			
		||||
	m_Log[LogTypes::PROCESSORINTERFACE]	= new LogContainer("PI",			"ProcessorInt");
 | 
			
		||||
	m_Log[LogTypes::MEMMAP]				= new LogContainer("MI",			"MI & memmap");
 | 
			
		||||
	m_Log[LogTypes::SP1]				= new LogContainer("SP1",			"Serial Port 1");
 | 
			
		||||
	m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream",		"StreamingInt");
 | 
			
		||||
	m_Log[LogTypes::DSPINTERFACE]		= new LogContainer("DSP",			"DSPInterface");
 | 
			
		||||
	m_Log[LogTypes::DVDINTERFACE]		= new LogContainer("DVD",			"DVDInterface");
 | 
			
		||||
	m_Log[LogTypes::GPFIFO]				= new LogContainer("GP",			"GPFifo");
 | 
			
		||||
	m_Log[LogTypes::EXPANSIONINTERFACE]	= new LogContainer("EXI",			"ExpansionInt");
 | 
			
		||||
	m_Log[LogTypes::GDB_STUB]			= new LogContainer("GDB_STUB",		"GDB Stub");
 | 
			
		||||
	m_Log[LogTypes::AUDIO_INTERFACE]	= new LogContainer("AI",			"AudioInt");
 | 
			
		||||
	m_Log[LogTypes::ARM11]				= new LogContainer("ARM11",			"ARM11");
 | 
			
		||||
	m_Log[LogTypes::OSHLE]				= new LogContainer("HLE",			"HLE");
 | 
			
		||||
	m_Log[LogTypes::DSPHLE]				= new LogContainer("DSPHLE",		"DSP HLE");
 | 
			
		||||
	m_Log[LogTypes::DSPLLE]				= new LogContainer("DSPLLE",		"DSP LLE");
 | 
			
		||||
	m_Log[LogTypes::DSP_MAIL]			= new LogContainer("DSPMails",		"DSP Mails");
 | 
			
		||||
	m_Log[LogTypes::VIDEO]				= new LogContainer("Video",			"Video Backend");
 | 
			
		||||
	m_Log[LogTypes::AUDIO]				= new LogContainer("Audio",			"Audio Emulator");
 | 
			
		||||
	m_Log[LogTypes::DYNA_REC]			= new LogContainer("JIT",			"Dynamic Recompiler");
 | 
			
		||||
	m_Log[LogTypes::CONSOLE]			= new LogContainer("CONSOLE",		"Dolphin Console");
 | 
			
		||||
	m_Log[LogTypes::OSREPORT]			= new LogContainer("OSREPORT",		"OSReport");
 | 
			
		||||
	m_Log[LogTypes::TIME]				= new LogContainer("Time",			"Core Timing");
 | 
			
		||||
	m_Log[LogTypes::LOADER]				= new LogContainer("Loader",		"Loader");
 | 
			
		||||
	m_Log[LogTypes::FILESYS]			= new LogContainer("FileSys",		"File System");
 | 
			
		||||
	m_Log[LogTypes::WII_IPC_HID]		= new LogContainer("WII_IPC_HID",	"WII IPC HID");
 | 
			
		||||
	m_Log[LogTypes::WII_IPC_HLE]		= new LogContainer("WII_IPC_HLE",	"WII IPC HLE");
 | 
			
		||||
	m_Log[LogTypes::WII_IPC_DVD]		= new LogContainer("WII_IPC_DVD",	"WII IPC DVD");
 | 
			
		||||
	m_Log[LogTypes::WII_IPC_ES]			= new LogContainer("WII_IPC_ES",	"WII IPC ES");
 | 
			
		||||
	m_Log[LogTypes::WII_IPC_FILEIO]		= new LogContainer("WII_IPC_FILEIO","WII IPC FILEIO");
 | 
			
		||||
	m_Log[LogTypes::WII_IPC_SD]			= new LogContainer("WII_IPC_SD",	"WII IPC SD");
 | 
			
		||||
	m_Log[LogTypes::WII_IPC_STM]		= new LogContainer("WII_IPC_STM",	"WII IPC STM");
 | 
			
		||||
	m_Log[LogTypes::WII_IPC_NET]		= new LogContainer("WII_IPC_NET",	"WII IPC NET");
 | 
			
		||||
	m_Log[LogTypes::WII_IPC_WC24]		= new LogContainer("WII_IPC_WC24",	"WII IPC WC24");
 | 
			
		||||
	m_Log[LogTypes::WII_IPC_SSL]		= new LogContainer("WII_IPC_SSL",	"WII IPC SSL");
 | 
			
		||||
	m_Log[LogTypes::WII_IPC_WIIMOTE]	= new LogContainer("WII_IPC_WIIMOTE","WII IPC WIIMOTE");
 | 
			
		||||
	m_Log[LogTypes::ACTIONREPLAY]		= new LogContainer("ActionReplay",	"ActionReplay");
 | 
			
		||||
	m_Log[LogTypes::MEMCARD_MANAGER]	= new LogContainer("MemCard Manager", "MemCard Manager");
 | 
			
		||||
	m_Log[LogTypes::NETPLAY]			= new LogContainer("NETPLAY",		"Netplay");
 | 
			
		||||
    // create log files
 | 
			
		||||
    m_Log[LogTypes::MASTER_LOG]            = new LogContainer("*",                "Master Log");
 | 
			
		||||
    m_Log[LogTypes::BOOT]                = new LogContainer("BOOT",            "Boot");
 | 
			
		||||
    m_Log[LogTypes::COMMON]                = new LogContainer("COMMON",        "Common");
 | 
			
		||||
    m_Log[LogTypes::DISCIO]                = new LogContainer("DIO",            "Disc IO");
 | 
			
		||||
    m_Log[LogTypes::FILEMON]            = new LogContainer("FileMon",        "File Monitor");
 | 
			
		||||
    m_Log[LogTypes::PAD]                = new LogContainer("PAD",            "Pad");
 | 
			
		||||
    m_Log[LogTypes::PIXELENGINE]        = new LogContainer("PE",            "PixelEngine");
 | 
			
		||||
    m_Log[LogTypes::COMMANDPROCESSOR]    = new LogContainer("CP",            "CommandProc");
 | 
			
		||||
    m_Log[LogTypes::VIDEOINTERFACE]        = new LogContainer("VI",            "VideoInt");
 | 
			
		||||
    m_Log[LogTypes::SERIALINTERFACE]    = new LogContainer("SI",            "SerialInt");
 | 
			
		||||
    m_Log[LogTypes::PROCESSORINTERFACE]    = new LogContainer("PI",            "ProcessorInt");
 | 
			
		||||
    m_Log[LogTypes::MEMMAP]                = new LogContainer("MI",            "MI & memmap");
 | 
			
		||||
    m_Log[LogTypes::SP1]                = new LogContainer("SP1",            "Serial Port 1");
 | 
			
		||||
    m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream",        "StreamingInt");
 | 
			
		||||
    m_Log[LogTypes::DSPINTERFACE]        = new LogContainer("DSP",            "DSPInterface");
 | 
			
		||||
    m_Log[LogTypes::DVDINTERFACE]        = new LogContainer("DVD",            "DVDInterface");
 | 
			
		||||
    m_Log[LogTypes::GPFIFO]                = new LogContainer("GP",            "GPFifo");
 | 
			
		||||
    m_Log[LogTypes::EXPANSIONINTERFACE]    = new LogContainer("EXI",            "ExpansionInt");
 | 
			
		||||
    m_Log[LogTypes::GDB_STUB]            = new LogContainer("GDB_STUB",        "GDB Stub");
 | 
			
		||||
    m_Log[LogTypes::AUDIO_INTERFACE]    = new LogContainer("AI",            "AudioInt");
 | 
			
		||||
    m_Log[LogTypes::ARM11]                = new LogContainer("ARM11",            "ARM11");
 | 
			
		||||
    m_Log[LogTypes::OSHLE]                = new LogContainer("HLE",            "HLE");
 | 
			
		||||
    m_Log[LogTypes::DSPHLE]                = new LogContainer("DSPHLE",        "DSP HLE");
 | 
			
		||||
    m_Log[LogTypes::DSPLLE]                = new LogContainer("DSPLLE",        "DSP LLE");
 | 
			
		||||
    m_Log[LogTypes::DSP_MAIL]            = new LogContainer("DSPMails",        "DSP Mails");
 | 
			
		||||
    m_Log[LogTypes::VIDEO]                = new LogContainer("Video",            "Video Backend");
 | 
			
		||||
    m_Log[LogTypes::AUDIO]                = new LogContainer("Audio",            "Audio Emulator");
 | 
			
		||||
    m_Log[LogTypes::DYNA_REC]            = new LogContainer("JIT",            "Dynamic Recompiler");
 | 
			
		||||
    m_Log[LogTypes::CONSOLE]            = new LogContainer("CONSOLE",        "Dolphin Console");
 | 
			
		||||
    m_Log[LogTypes::OSREPORT]            = new LogContainer("OSREPORT",        "OSReport");
 | 
			
		||||
    m_Log[LogTypes::TIME]                = new LogContainer("Time",            "Core Timing");
 | 
			
		||||
    m_Log[LogTypes::LOADER]                = new LogContainer("Loader",        "Loader");
 | 
			
		||||
    m_Log[LogTypes::FILESYS]            = new LogContainer("FileSys",        "File System");
 | 
			
		||||
    m_Log[LogTypes::WII_IPC_HID]        = new LogContainer("WII_IPC_HID",    "WII IPC HID");
 | 
			
		||||
    m_Log[LogTypes::WII_IPC_HLE]        = new LogContainer("WII_IPC_HLE",    "WII IPC HLE");
 | 
			
		||||
    m_Log[LogTypes::WII_IPC_DVD]        = new LogContainer("WII_IPC_DVD",    "WII IPC DVD");
 | 
			
		||||
    m_Log[LogTypes::WII_IPC_ES]            = new LogContainer("WII_IPC_ES",    "WII IPC ES");
 | 
			
		||||
    m_Log[LogTypes::WII_IPC_FILEIO]        = new LogContainer("WII_IPC_FILEIO","WII IPC FILEIO");
 | 
			
		||||
    m_Log[LogTypes::WII_IPC_SD]            = new LogContainer("WII_IPC_SD",    "WII IPC SD");
 | 
			
		||||
    m_Log[LogTypes::WII_IPC_STM]        = new LogContainer("WII_IPC_STM",    "WII IPC STM");
 | 
			
		||||
    m_Log[LogTypes::WII_IPC_NET]        = new LogContainer("WII_IPC_NET",    "WII IPC NET");
 | 
			
		||||
    m_Log[LogTypes::WII_IPC_WC24]        = new LogContainer("WII_IPC_WC24",    "WII IPC WC24");
 | 
			
		||||
    m_Log[LogTypes::WII_IPC_SSL]        = new LogContainer("WII_IPC_SSL",    "WII IPC SSL");
 | 
			
		||||
    m_Log[LogTypes::WII_IPC_WIIMOTE]    = new LogContainer("WII_IPC_WIIMOTE","WII IPC WIIMOTE");
 | 
			
		||||
    m_Log[LogTypes::ACTIONREPLAY]        = new LogContainer("ActionReplay",    "ActionReplay");
 | 
			
		||||
    m_Log[LogTypes::MEMCARD_MANAGER]    = new LogContainer("MemCard Manager", "MemCard Manager");
 | 
			
		||||
    m_Log[LogTypes::NETPLAY]            = new LogContainer("NETPLAY",        "Netplay");
 | 
			
		||||
 | 
			
		||||
	m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str());
 | 
			
		||||
	m_consoleLog = new ConsoleListener();
 | 
			
		||||
	m_debuggerLog = new DebuggerLogListener();
 | 
			
		||||
    m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str());
 | 
			
		||||
    m_consoleLog = new ConsoleListener();
 | 
			
		||||
    m_debuggerLog = new DebuggerLogListener();
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		m_Log[i]->SetEnable(true);
 | 
			
		||||
		m_Log[i]->AddListener(m_fileLog);
 | 
			
		||||
		m_Log[i]->AddListener(m_consoleLog);
 | 
			
		||||
    for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        m_Log[i]->SetEnable(true);
 | 
			
		||||
        m_Log[i]->AddListener(m_fileLog);
 | 
			
		||||
        m_Log[i]->AddListener(m_consoleLog);
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
		if (IsDebuggerPresent())
 | 
			
		||||
			m_Log[i]->AddListener(m_debuggerLog);
 | 
			
		||||
        if (IsDebuggerPresent())
 | 
			
		||||
            m_Log[i]->AddListener(m_debuggerLog);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LogManager::~LogManager()
 | 
			
		||||
{
 | 
			
		||||
	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_fileLog);
 | 
			
		||||
		m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog);
 | 
			
		||||
		m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_debuggerLog);
 | 
			
		||||
	}
 | 
			
		||||
    for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_fileLog);
 | 
			
		||||
        m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog);
 | 
			
		||||
        m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_debuggerLog);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
 | 
			
		||||
		delete m_Log[i];
 | 
			
		||||
    for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
 | 
			
		||||
        delete m_Log[i];
 | 
			
		||||
 | 
			
		||||
	delete m_fileLog;
 | 
			
		||||
	delete m_consoleLog;
 | 
			
		||||
	delete m_debuggerLog;
 | 
			
		||||
    delete m_fileLog;
 | 
			
		||||
    delete m_consoleLog;
 | 
			
		||||
    delete m_debuggerLog;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, 
 | 
			
		||||
	const char *file, int line, const char *format, va_list args)
 | 
			
		||||
    const char *file, int line, const char *format, va_list args)
 | 
			
		||||
{
 | 
			
		||||
	char temp[MAX_MSGLEN];
 | 
			
		||||
	char msg[MAX_MSGLEN * 2];
 | 
			
		||||
	LogContainer *log = m_Log[type];
 | 
			
		||||
    char temp[MAX_MSGLEN];
 | 
			
		||||
    char msg[MAX_MSGLEN * 2];
 | 
			
		||||
    LogContainer *log = m_Log[type];
 | 
			
		||||
 | 
			
		||||
	if (!log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners())
 | 
			
		||||
		return;
 | 
			
		||||
    if (!log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
	CharArrayFromFormatV(temp, MAX_MSGLEN, format, args);
 | 
			
		||||
    CharArrayFromFormatV(temp, MAX_MSGLEN, format, args);
 | 
			
		||||
 | 
			
		||||
	static const char level_to_char[7] = "-NEWID";
 | 
			
		||||
	sprintf(msg, "%s %s:%u %c[%s]: %s\n",
 | 
			
		||||
		Common::Timer::GetTimeFormatted().c_str(),
 | 
			
		||||
		file, line, level_to_char[(int)level],
 | 
			
		||||
		log->GetShortName(), temp);
 | 
			
		||||
    static const char level_to_char[7] = "-NEWID";
 | 
			
		||||
    sprintf(msg, "%s %s:%u %c[%s]: %s\n",
 | 
			
		||||
        Common::Timer::GetTimeFormatted().c_str(),
 | 
			
		||||
        file, line, level_to_char[(int)level],
 | 
			
		||||
        log->GetShortName(), temp);
 | 
			
		||||
#ifdef ANDROID
 | 
			
		||||
	Host_SysMessage(msg);	
 | 
			
		||||
    Host_SysMessage(msg);    
 | 
			
		||||
#endif
 | 
			
		||||
	printf(msg); // TODO(ShizZy): RemoveMe when I no longer need this
 | 
			
		||||
	log->Trigger(level, msg);
 | 
			
		||||
    printf(msg); // TODO(ShizZy): RemoveMe when I no longer need this
 | 
			
		||||
    log->Trigger(level, msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LogManager::Init()
 | 
			
		||||
{
 | 
			
		||||
	m_logManager = new LogManager();
 | 
			
		||||
    m_logManager = new LogManager();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LogManager::Shutdown()
 | 
			
		||||
{
 | 
			
		||||
	delete m_logManager;
 | 
			
		||||
	m_logManager = NULL;
 | 
			
		||||
    delete m_logManager;
 | 
			
		||||
    m_logManager = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LogContainer::LogContainer(const char* shortName, const char* fullName, bool enable)
 | 
			
		||||
	: m_enable(enable)
 | 
			
		||||
    : m_enable(enable)
 | 
			
		||||
{
 | 
			
		||||
	strncpy(m_fullName, fullName, 128);
 | 
			
		||||
	strncpy(m_shortName, shortName, 32);
 | 
			
		||||
	m_level = LogTypes::LWARNING;
 | 
			
		||||
    strncpy(m_fullName, fullName, 128);
 | 
			
		||||
    strncpy(m_shortName, shortName, 32);
 | 
			
		||||
    m_level = LogTypes::LWARNING;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LogContainer
 | 
			
		||||
void LogContainer::AddListener(LogListener *listener)
 | 
			
		||||
{
 | 
			
		||||
	std::lock_guard<std::mutex> lk(m_listeners_lock);
 | 
			
		||||
	m_listeners.insert(listener);
 | 
			
		||||
    std::lock_guard<std::mutex> lk(m_listeners_lock);
 | 
			
		||||
    m_listeners.insert(listener);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LogContainer::RemoveListener(LogListener *listener)
 | 
			
		||||
{
 | 
			
		||||
	std::lock_guard<std::mutex> lk(m_listeners_lock);
 | 
			
		||||
	m_listeners.erase(listener);
 | 
			
		||||
    std::lock_guard<std::mutex> lk(m_listeners_lock);
 | 
			
		||||
    m_listeners.erase(listener);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LogContainer::Trigger(LogTypes::LOG_LEVELS level, const char *msg)
 | 
			
		||||
{
 | 
			
		||||
	std::lock_guard<std::mutex> lk(m_listeners_lock);
 | 
			
		||||
    std::lock_guard<std::mutex> lk(m_listeners_lock);
 | 
			
		||||
 | 
			
		||||
	std::set<LogListener*>::const_iterator i;
 | 
			
		||||
	for (i = m_listeners.begin(); i != m_listeners.end(); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		(*i)->Log(level, msg);
 | 
			
		||||
	}
 | 
			
		||||
    std::set<LogListener*>::const_iterator i;
 | 
			
		||||
    for (i = m_listeners.begin(); i != m_listeners.end(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        (*i)->Log(level, msg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FileLogListener::FileLogListener(const char *filename)
 | 
			
		||||
{
 | 
			
		||||
	OpenFStream(m_logfile, filename, std::ios::app);
 | 
			
		||||
	SetEnable(true);
 | 
			
		||||
    OpenFStream(m_logfile, filename, std::ios::app);
 | 
			
		||||
    SetEnable(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg)
 | 
			
		||||
{
 | 
			
		||||
	if (!IsEnabled() || !IsValid())
 | 
			
		||||
		return;
 | 
			
		||||
    if (!IsEnabled() || !IsValid())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
	std::lock_guard<std::mutex> lk(m_log_lock);
 | 
			
		||||
	m_logfile << msg << std::flush;
 | 
			
		||||
    std::lock_guard<std::mutex> lk(m_log_lock);
 | 
			
		||||
    m_logfile << msg << std::flush;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DebuggerLogListener::Log(LogTypes::LOG_LEVELS, const char *msg)
 | 
			
		||||
{
 | 
			
		||||
#if _MSC_VER
 | 
			
		||||
	::OutputDebugStringA(msg);
 | 
			
		||||
    ::OutputDebugStringA(msg);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,65 +21,65 @@
 | 
			
		||||
class LogListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	virtual ~LogListener() {}
 | 
			
		||||
    virtual ~LogListener() {}
 | 
			
		||||
 | 
			
		||||
	virtual void Log(LogTypes::LOG_LEVELS, const char *msg) = 0;
 | 
			
		||||
    virtual void Log(LogTypes::LOG_LEVELS, const char *msg) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class FileLogListener : public LogListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	FileLogListener(const char *filename);
 | 
			
		||||
    FileLogListener(const char *filename);
 | 
			
		||||
 | 
			
		||||
	void Log(LogTypes::LOG_LEVELS, const char *msg);
 | 
			
		||||
    void Log(LogTypes::LOG_LEVELS, const char *msg);
 | 
			
		||||
 | 
			
		||||
	bool IsValid() { return !m_logfile.fail(); }
 | 
			
		||||
	bool IsEnabled() const { return m_enable; }
 | 
			
		||||
	void SetEnable(bool enable) { m_enable = enable; }
 | 
			
		||||
    bool IsValid() { return !m_logfile.fail(); }
 | 
			
		||||
    bool IsEnabled() const { return m_enable; }
 | 
			
		||||
    void SetEnable(bool enable) { m_enable = enable; }
 | 
			
		||||
 | 
			
		||||
	const char* GetName() const { return "file"; }
 | 
			
		||||
    const char* GetName() const { return "file"; }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	std::mutex m_log_lock;
 | 
			
		||||
	std::ofstream m_logfile;
 | 
			
		||||
	bool m_enable;
 | 
			
		||||
    std::mutex m_log_lock;
 | 
			
		||||
    std::ofstream m_logfile;
 | 
			
		||||
    bool m_enable;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class DebuggerLogListener : public LogListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	void Log(LogTypes::LOG_LEVELS, const char *msg);
 | 
			
		||||
    void Log(LogTypes::LOG_LEVELS, const char *msg);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LogContainer
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	LogContainer(const char* shortName, const char* fullName, bool enable = false);
 | 
			
		||||
	
 | 
			
		||||
	const char* GetShortName() const { return m_shortName; }
 | 
			
		||||
	const char* GetFullName() const { return m_fullName; }
 | 
			
		||||
    LogContainer(const char* shortName, const char* fullName, bool enable = false);
 | 
			
		||||
    
 | 
			
		||||
    const char* GetShortName() const { return m_shortName; }
 | 
			
		||||
    const char* GetFullName() const { return m_fullName; }
 | 
			
		||||
 | 
			
		||||
	void AddListener(LogListener* listener);
 | 
			
		||||
	void RemoveListener(LogListener* listener);
 | 
			
		||||
    void AddListener(LogListener* listener);
 | 
			
		||||
    void RemoveListener(LogListener* listener);
 | 
			
		||||
 | 
			
		||||
	void Trigger(LogTypes::LOG_LEVELS, const char *msg);
 | 
			
		||||
    void Trigger(LogTypes::LOG_LEVELS, const char *msg);
 | 
			
		||||
 | 
			
		||||
	bool IsEnabled() const { return m_enable; }
 | 
			
		||||
	void SetEnable(bool enable) { m_enable = enable; }
 | 
			
		||||
    bool IsEnabled() const { return m_enable; }
 | 
			
		||||
    void SetEnable(bool enable) { m_enable = enable; }
 | 
			
		||||
 | 
			
		||||
	LogTypes::LOG_LEVELS GetLevel() const { return m_level;	}
 | 
			
		||||
    LogTypes::LOG_LEVELS GetLevel() const { return m_level;    }
 | 
			
		||||
 | 
			
		||||
	void SetLevel(LogTypes::LOG_LEVELS level) {	m_level = level; }
 | 
			
		||||
    void SetLevel(LogTypes::LOG_LEVELS level) {    m_level = level; }
 | 
			
		||||
 | 
			
		||||
	bool HasListeners() const { return !m_listeners.empty(); }
 | 
			
		||||
    bool HasListeners() const { return !m_listeners.empty(); }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	char m_fullName[128];
 | 
			
		||||
	char m_shortName[32];
 | 
			
		||||
	bool m_enable;
 | 
			
		||||
	LogTypes::LOG_LEVELS m_level;
 | 
			
		||||
	std::mutex m_listeners_lock;
 | 
			
		||||
	std::set<LogListener*> m_listeners;
 | 
			
		||||
    char m_fullName[128];
 | 
			
		||||
    char m_shortName[32];
 | 
			
		||||
    bool m_enable;
 | 
			
		||||
    LogTypes::LOG_LEVELS m_level;
 | 
			
		||||
    std::mutex m_listeners_lock;
 | 
			
		||||
    std::set<LogListener*> m_listeners;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ConsoleListener;
 | 
			
		||||
@@ -87,83 +87,83 @@ class ConsoleListener;
 | 
			
		||||
class LogManager : NonCopyable
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
	LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS];
 | 
			
		||||
	FileLogListener *m_fileLog;
 | 
			
		||||
	ConsoleListener *m_consoleLog;
 | 
			
		||||
	DebuggerLogListener *m_debuggerLog;
 | 
			
		||||
	static LogManager *m_logManager;  // Singleton. Ugh.
 | 
			
		||||
    LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS];
 | 
			
		||||
    FileLogListener *m_fileLog;
 | 
			
		||||
    ConsoleListener *m_consoleLog;
 | 
			
		||||
    DebuggerLogListener *m_debuggerLog;
 | 
			
		||||
    static LogManager *m_logManager;  // Singleton. Ugh.
 | 
			
		||||
 | 
			
		||||
	LogManager();
 | 
			
		||||
	~LogManager();
 | 
			
		||||
    LogManager();
 | 
			
		||||
    ~LogManager();
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	static u32 GetMaxLevel() { return MAX_LOGLEVEL;	}
 | 
			
		||||
    static u32 GetMaxLevel() { return MAX_LOGLEVEL;    }
 | 
			
		||||
 | 
			
		||||
	void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, 
 | 
			
		||||
			 const char *file, int line, const char *fmt, va_list args);
 | 
			
		||||
    void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, 
 | 
			
		||||
             const char *file, int line, const char *fmt, va_list args);
 | 
			
		||||
 | 
			
		||||
	void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level)
 | 
			
		||||
	{
 | 
			
		||||
		m_Log[type]->SetLevel(level);
 | 
			
		||||
	}
 | 
			
		||||
    void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level)
 | 
			
		||||
    {
 | 
			
		||||
        m_Log[type]->SetLevel(level);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void SetEnable(LogTypes::LOG_TYPE type, bool enable)
 | 
			
		||||
	{
 | 
			
		||||
		m_Log[type]->SetEnable(enable);
 | 
			
		||||
	}
 | 
			
		||||
    void SetEnable(LogTypes::LOG_TYPE type, bool enable)
 | 
			
		||||
    {
 | 
			
		||||
        m_Log[type]->SetEnable(enable);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	bool IsEnabled(LogTypes::LOG_TYPE type) const
 | 
			
		||||
	{
 | 
			
		||||
		return m_Log[type]->IsEnabled();
 | 
			
		||||
	}
 | 
			
		||||
    bool IsEnabled(LogTypes::LOG_TYPE type) const
 | 
			
		||||
    {
 | 
			
		||||
        return m_Log[type]->IsEnabled();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	const char* GetShortName(LogTypes::LOG_TYPE type) const
 | 
			
		||||
	{
 | 
			
		||||
		return m_Log[type]->GetShortName();
 | 
			
		||||
	}
 | 
			
		||||
    const char* GetShortName(LogTypes::LOG_TYPE type) const
 | 
			
		||||
    {
 | 
			
		||||
        return m_Log[type]->GetShortName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	const char* GetFullName(LogTypes::LOG_TYPE type) const
 | 
			
		||||
	{
 | 
			
		||||
		return m_Log[type]->GetFullName();
 | 
			
		||||
	}
 | 
			
		||||
    const char* GetFullName(LogTypes::LOG_TYPE type) const
 | 
			
		||||
    {
 | 
			
		||||
        return m_Log[type]->GetFullName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void AddListener(LogTypes::LOG_TYPE type, LogListener *listener)
 | 
			
		||||
	{
 | 
			
		||||
		m_Log[type]->AddListener(listener);
 | 
			
		||||
	}
 | 
			
		||||
    void AddListener(LogTypes::LOG_TYPE type, LogListener *listener)
 | 
			
		||||
    {
 | 
			
		||||
        m_Log[type]->AddListener(listener);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener)
 | 
			
		||||
	{
 | 
			
		||||
		m_Log[type]->RemoveListener(listener);
 | 
			
		||||
	}
 | 
			
		||||
    void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener)
 | 
			
		||||
    {
 | 
			
		||||
        m_Log[type]->RemoveListener(listener);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	FileLogListener *GetFileListener() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_fileLog;
 | 
			
		||||
	}
 | 
			
		||||
    FileLogListener *GetFileListener() const
 | 
			
		||||
    {
 | 
			
		||||
        return m_fileLog;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	ConsoleListener *GetConsoleListener() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_consoleLog;
 | 
			
		||||
	}
 | 
			
		||||
    ConsoleListener *GetConsoleListener() const
 | 
			
		||||
    {
 | 
			
		||||
        return m_consoleLog;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	DebuggerLogListener *GetDebuggerListener() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_debuggerLog;
 | 
			
		||||
	}
 | 
			
		||||
    DebuggerLogListener *GetDebuggerListener() const
 | 
			
		||||
    {
 | 
			
		||||
        return m_debuggerLog;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	static LogManager* GetInstance()
 | 
			
		||||
	{
 | 
			
		||||
		return m_logManager;
 | 
			
		||||
	}
 | 
			
		||||
    static LogManager* GetInstance()
 | 
			
		||||
    {
 | 
			
		||||
        return m_logManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	static void SetInstance(LogManager *logManager)
 | 
			
		||||
	{
 | 
			
		||||
		m_logManager = logManager;
 | 
			
		||||
	}
 | 
			
		||||
    static void SetInstance(LogManager *logManager)
 | 
			
		||||
    {
 | 
			
		||||
        m_logManager = logManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	static void Init();
 | 
			
		||||
	static void Shutdown();
 | 
			
		||||
    static void Init();
 | 
			
		||||
    static void Shutdown();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _LOGMANAGER_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -14,82 +14,82 @@ namespace MathUtil
 | 
			
		||||
 | 
			
		||||
u32 ClassifyDouble(double dvalue)
 | 
			
		||||
{
 | 
			
		||||
	// TODO: Optimize the below to be as fast as possible.
 | 
			
		||||
	IntDouble value;
 | 
			
		||||
	value.d = dvalue;
 | 
			
		||||
	u64 sign = value.i & DOUBLE_SIGN;
 | 
			
		||||
	u64 exp  = value.i & DOUBLE_EXP;
 | 
			
		||||
	if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP) 
 | 
			
		||||
	{
 | 
			
		||||
		// Nice normalized number.
 | 
			
		||||
		return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		u64 mantissa = value.i & DOUBLE_FRAC;
 | 
			
		||||
		if (mantissa)
 | 
			
		||||
		{
 | 
			
		||||
			if (exp)
 | 
			
		||||
			{
 | 
			
		||||
				return PPC_FPCLASS_QNAN;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				// Denormalized number.
 | 
			
		||||
				return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (exp)
 | 
			
		||||
		{
 | 
			
		||||
			//Infinite
 | 
			
		||||
			return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			//Zero
 | 
			
		||||
			return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    // TODO: Optimize the below to be as fast as possible.
 | 
			
		||||
    IntDouble value;
 | 
			
		||||
    value.d = dvalue;
 | 
			
		||||
    u64 sign = value.i & DOUBLE_SIGN;
 | 
			
		||||
    u64 exp  = value.i & DOUBLE_EXP;
 | 
			
		||||
    if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP) 
 | 
			
		||||
    {
 | 
			
		||||
        // Nice normalized number.
 | 
			
		||||
        return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        u64 mantissa = value.i & DOUBLE_FRAC;
 | 
			
		||||
        if (mantissa)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp)
 | 
			
		||||
            {
 | 
			
		||||
                return PPC_FPCLASS_QNAN;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // Denormalized number.
 | 
			
		||||
                return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (exp)
 | 
			
		||||
        {
 | 
			
		||||
            //Infinite
 | 
			
		||||
            return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            //Zero
 | 
			
		||||
            return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 ClassifyFloat(float fvalue)
 | 
			
		||||
{
 | 
			
		||||
	// TODO: Optimize the below to be as fast as possible.
 | 
			
		||||
	IntFloat value;
 | 
			
		||||
	value.f = fvalue;
 | 
			
		||||
	u32 sign = value.i & FLOAT_SIGN;
 | 
			
		||||
	u32 exp  = value.i & FLOAT_EXP;
 | 
			
		||||
	if (exp > FLOAT_ZERO && exp < FLOAT_EXP) 
 | 
			
		||||
	{
 | 
			
		||||
		// Nice normalized number.
 | 
			
		||||
		return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		u32 mantissa = value.i & FLOAT_FRAC;
 | 
			
		||||
		if (mantissa)
 | 
			
		||||
		{
 | 
			
		||||
			if (exp)
 | 
			
		||||
			{
 | 
			
		||||
				return PPC_FPCLASS_QNAN; // Quiet NAN
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				// Denormalized number.
 | 
			
		||||
				return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
 | 
			
		||||
			}
 | 
			
		||||
		} 
 | 
			
		||||
		else if (exp) 
 | 
			
		||||
		{
 | 
			
		||||
			// Infinite
 | 
			
		||||
			return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
 | 
			
		||||
		} 
 | 
			
		||||
		else 
 | 
			
		||||
		{
 | 
			
		||||
			//Zero
 | 
			
		||||
			return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    // TODO: Optimize the below to be as fast as possible.
 | 
			
		||||
    IntFloat value;
 | 
			
		||||
    value.f = fvalue;
 | 
			
		||||
    u32 sign = value.i & FLOAT_SIGN;
 | 
			
		||||
    u32 exp  = value.i & FLOAT_EXP;
 | 
			
		||||
    if (exp > FLOAT_ZERO && exp < FLOAT_EXP) 
 | 
			
		||||
    {
 | 
			
		||||
        // Nice normalized number.
 | 
			
		||||
        return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        u32 mantissa = value.i & FLOAT_FRAC;
 | 
			
		||||
        if (mantissa)
 | 
			
		||||
        {
 | 
			
		||||
            if (exp)
 | 
			
		||||
            {
 | 
			
		||||
                return PPC_FPCLASS_QNAN; // Quiet NAN
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // Denormalized number.
 | 
			
		||||
                return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
 | 
			
		||||
            }
 | 
			
		||||
        } 
 | 
			
		||||
        else if (exp) 
 | 
			
		||||
        {
 | 
			
		||||
            // Infinite
 | 
			
		||||
            return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
 | 
			
		||||
        } 
 | 
			
		||||
        else 
 | 
			
		||||
        {
 | 
			
		||||
            //Zero
 | 
			
		||||
            return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -97,116 +97,116 @@ u32 ClassifyFloat(float fvalue)
 | 
			
		||||
 | 
			
		||||
inline void MatrixMul(int n, const float *a, const float *b, float *result)
 | 
			
		||||
{
 | 
			
		||||
	for (int i = 0; i < n; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		for (int j = 0; j < n; ++j)
 | 
			
		||||
		{
 | 
			
		||||
			float temp = 0;
 | 
			
		||||
			for (int k = 0; k < n; ++k)
 | 
			
		||||
			{
 | 
			
		||||
				temp += a[i * n + k] * b[k * n + j];
 | 
			
		||||
			}
 | 
			
		||||
			result[i * n + j] = temp;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    for (int i = 0; i < n; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        for (int j = 0; j < n; ++j)
 | 
			
		||||
        {
 | 
			
		||||
            float temp = 0;
 | 
			
		||||
            for (int k = 0; k < n; ++k)
 | 
			
		||||
            {
 | 
			
		||||
                temp += a[i * n + k] * b[k * n + j];
 | 
			
		||||
            }
 | 
			
		||||
            result[i * n + j] = temp;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Calculate sum of a float list
 | 
			
		||||
float MathFloatVectorSum(const std::vector<float>& Vec)
 | 
			
		||||
{
 | 
			
		||||
	return std::accumulate(Vec.begin(), Vec.end(), 0.0f);
 | 
			
		||||
    return std::accumulate(Vec.begin(), Vec.end(), 0.0f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Matrix33::LoadIdentity(Matrix33 &mtx)
 | 
			
		||||
{
 | 
			
		||||
	memset(mtx.data, 0, sizeof(mtx.data));
 | 
			
		||||
	mtx.data[0] = 1.0f;
 | 
			
		||||
	mtx.data[4] = 1.0f;
 | 
			
		||||
	mtx.data[8] = 1.0f;
 | 
			
		||||
    memset(mtx.data, 0, sizeof(mtx.data));
 | 
			
		||||
    mtx.data[0] = 1.0f;
 | 
			
		||||
    mtx.data[4] = 1.0f;
 | 
			
		||||
    mtx.data[8] = 1.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Matrix33::RotateX(Matrix33 &mtx, float rad)
 | 
			
		||||
{
 | 
			
		||||
	float s = sin(rad);
 | 
			
		||||
	float c = cos(rad);
 | 
			
		||||
	memset(mtx.data, 0, sizeof(mtx.data));
 | 
			
		||||
	mtx.data[0] = 1;
 | 
			
		||||
	mtx.data[4] = c;
 | 
			
		||||
	mtx.data[5] = -s;
 | 
			
		||||
	mtx.data[7] = s;
 | 
			
		||||
	mtx.data[8] = c;
 | 
			
		||||
    float s = sin(rad);
 | 
			
		||||
    float c = cos(rad);
 | 
			
		||||
    memset(mtx.data, 0, sizeof(mtx.data));
 | 
			
		||||
    mtx.data[0] = 1;
 | 
			
		||||
    mtx.data[4] = c;
 | 
			
		||||
    mtx.data[5] = -s;
 | 
			
		||||
    mtx.data[7] = s;
 | 
			
		||||
    mtx.data[8] = c;
 | 
			
		||||
}
 | 
			
		||||
void Matrix33::RotateY(Matrix33 &mtx, float rad)
 | 
			
		||||
{
 | 
			
		||||
	float s = sin(rad);
 | 
			
		||||
	float c = cos(rad);
 | 
			
		||||
	memset(mtx.data, 0, sizeof(mtx.data));
 | 
			
		||||
	mtx.data[0] = c;
 | 
			
		||||
	mtx.data[2] = s;
 | 
			
		||||
	mtx.data[4] = 1;
 | 
			
		||||
	mtx.data[6] = -s;    
 | 
			
		||||
	mtx.data[8] = c;
 | 
			
		||||
    float s = sin(rad);
 | 
			
		||||
    float c = cos(rad);
 | 
			
		||||
    memset(mtx.data, 0, sizeof(mtx.data));
 | 
			
		||||
    mtx.data[0] = c;
 | 
			
		||||
    mtx.data[2] = s;
 | 
			
		||||
    mtx.data[4] = 1;
 | 
			
		||||
    mtx.data[6] = -s;    
 | 
			
		||||
    mtx.data[8] = c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Matrix33::Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result)
 | 
			
		||||
{
 | 
			
		||||
	MatrixMul(3, a.data, b.data, result.data);
 | 
			
		||||
    MatrixMul(3, a.data, b.data, result.data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Matrix33::Multiply(const Matrix33 &a, const float vec[3], float result[3])
 | 
			
		||||
{
 | 
			
		||||
	for (int i = 0; i < 3; ++i) {
 | 
			
		||||
		result[i] = 0;
 | 
			
		||||
		for (int k = 0; k < 3; ++k) {
 | 
			
		||||
			result[i] += a.data[i * 3 + k] * vec[k];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    for (int i = 0; i < 3; ++i) {
 | 
			
		||||
        result[i] = 0;
 | 
			
		||||
        for (int k = 0; k < 3; ++k) {
 | 
			
		||||
            result[i] += a.data[i * 3 + k] * vec[k];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Matrix44::LoadIdentity(Matrix44 &mtx)
 | 
			
		||||
{
 | 
			
		||||
	memset(mtx.data, 0, sizeof(mtx.data));
 | 
			
		||||
	mtx.data[0] = 1.0f;
 | 
			
		||||
	mtx.data[5] = 1.0f;
 | 
			
		||||
	mtx.data[10] = 1.0f;
 | 
			
		||||
	mtx.data[15] = 1.0f;
 | 
			
		||||
    memset(mtx.data, 0, sizeof(mtx.data));
 | 
			
		||||
    mtx.data[0] = 1.0f;
 | 
			
		||||
    mtx.data[5] = 1.0f;
 | 
			
		||||
    mtx.data[10] = 1.0f;
 | 
			
		||||
    mtx.data[15] = 1.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Matrix44::LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33)
 | 
			
		||||
{
 | 
			
		||||
	for (int i = 0; i < 3; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		for (int j = 0; j < 3; ++j)
 | 
			
		||||
		{
 | 
			
		||||
			mtx.data[i * 4 + j] = m33.data[i * 3 + j];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    for (int i = 0; i < 3; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        for (int j = 0; j < 3; ++j)
 | 
			
		||||
        {
 | 
			
		||||
            mtx.data[i * 4 + j] = m33.data[i * 3 + j];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < 3; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		mtx.data[i * 4 + 3] = 0;
 | 
			
		||||
		mtx.data[i + 12] = 0;
 | 
			
		||||
	}
 | 
			
		||||
	mtx.data[15] = 1.0f;
 | 
			
		||||
    for (int i = 0; i < 3; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        mtx.data[i * 4 + 3] = 0;
 | 
			
		||||
        mtx.data[i + 12] = 0;
 | 
			
		||||
    }
 | 
			
		||||
    mtx.data[15] = 1.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Matrix44::Set(Matrix44 &mtx, const float mtxArray[16])
 | 
			
		||||
{
 | 
			
		||||
	for(int i = 0; i < 16; ++i) {
 | 
			
		||||
		mtx.data[i] = mtxArray[i];
 | 
			
		||||
	}
 | 
			
		||||
    for(int i = 0; i < 16; ++i) {
 | 
			
		||||
        mtx.data[i] = mtxArray[i];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Matrix44::Translate(Matrix44 &mtx, const float vec[3])
 | 
			
		||||
{
 | 
			
		||||
	LoadIdentity(mtx);
 | 
			
		||||
	mtx.data[3] = vec[0];
 | 
			
		||||
	mtx.data[7] = vec[1];
 | 
			
		||||
	mtx.data[11] = vec[2];
 | 
			
		||||
    LoadIdentity(mtx);
 | 
			
		||||
    mtx.data[3] = vec[0];
 | 
			
		||||
    mtx.data[7] = vec[1];
 | 
			
		||||
    mtx.data[11] = vec[2];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Matrix44::Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result)
 | 
			
		||||
{
 | 
			
		||||
	MatrixMul(4, a.data, b.data, result.data);
 | 
			
		||||
    MatrixMul(4, a.data, b.data, result.data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,74 +14,74 @@ namespace MathUtil
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
static const u64 DOUBLE_SIGN = 0x8000000000000000ULL,
 | 
			
		||||
	DOUBLE_EXP  = 0x7FF0000000000000ULL,
 | 
			
		||||
	DOUBLE_FRAC = 0x000FFFFFFFFFFFFFULL,
 | 
			
		||||
	DOUBLE_ZERO = 0x0000000000000000ULL;
 | 
			
		||||
    DOUBLE_EXP  = 0x7FF0000000000000ULL,
 | 
			
		||||
    DOUBLE_FRAC = 0x000FFFFFFFFFFFFFULL,
 | 
			
		||||
    DOUBLE_ZERO = 0x0000000000000000ULL;
 | 
			
		||||
 | 
			
		||||
static const u32 FLOAT_SIGN = 0x80000000,
 | 
			
		||||
	FLOAT_EXP  = 0x7F800000,
 | 
			
		||||
	FLOAT_FRAC = 0x007FFFFF,
 | 
			
		||||
	FLOAT_ZERO = 0x00000000;
 | 
			
		||||
    FLOAT_EXP  = 0x7F800000,
 | 
			
		||||
    FLOAT_FRAC = 0x007FFFFF,
 | 
			
		||||
    FLOAT_ZERO = 0x00000000;
 | 
			
		||||
 | 
			
		||||
union IntDouble {
 | 
			
		||||
	double d;
 | 
			
		||||
	u64 i;
 | 
			
		||||
    double d;
 | 
			
		||||
    u64 i;
 | 
			
		||||
};
 | 
			
		||||
union IntFloat {
 | 
			
		||||
	float f;
 | 
			
		||||
	u32 i;
 | 
			
		||||
    float f;
 | 
			
		||||
    u32 i;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline bool IsNAN(double d)
 | 
			
		||||
{
 | 
			
		||||
	IntDouble x; x.d = d;
 | 
			
		||||
	return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
 | 
			
		||||
			 ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) );
 | 
			
		||||
    IntDouble x; x.d = d;
 | 
			
		||||
    return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
 | 
			
		||||
             ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool IsQNAN(double d)
 | 
			
		||||
{
 | 
			
		||||
	IntDouble x; x.d = d;
 | 
			
		||||
	return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
 | 
			
		||||
		     ((x.i & 0x0007fffffffffffULL) == 0x000000000000000ULL) &&
 | 
			
		||||
		     ((x.i & 0x000800000000000ULL) == 0x000800000000000ULL) );
 | 
			
		||||
    IntDouble x; x.d = d;
 | 
			
		||||
    return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
 | 
			
		||||
             ((x.i & 0x0007fffffffffffULL) == 0x000000000000000ULL) &&
 | 
			
		||||
             ((x.i & 0x000800000000000ULL) == 0x000800000000000ULL) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool IsSNAN(double d)
 | 
			
		||||
{
 | 
			
		||||
	IntDouble x; x.d = d;
 | 
			
		||||
	return( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
 | 
			
		||||
			((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) &&
 | 
			
		||||
			((x.i & 0x0008000000000000ULL) == DOUBLE_ZERO) );
 | 
			
		||||
    IntDouble x; x.d = d;
 | 
			
		||||
    return( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
 | 
			
		||||
            ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) &&
 | 
			
		||||
            ((x.i & 0x0008000000000000ULL) == DOUBLE_ZERO) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline float FlushToZero(float f)
 | 
			
		||||
{
 | 
			
		||||
	IntFloat x; x.f = f;
 | 
			
		||||
	if ((x.i & FLOAT_EXP) == 0)
 | 
			
		||||
		x.i &= FLOAT_SIGN;  // turn into signed zero
 | 
			
		||||
	return x.f;
 | 
			
		||||
    IntFloat x; x.f = f;
 | 
			
		||||
    if ((x.i & FLOAT_EXP) == 0)
 | 
			
		||||
        x.i &= FLOAT_SIGN;  // turn into signed zero
 | 
			
		||||
    return x.f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline double FlushToZeroAsFloat(double d)
 | 
			
		||||
{
 | 
			
		||||
	IntDouble x; x.d = d;
 | 
			
		||||
	if ((x.i & DOUBLE_EXP) < 0x3800000000000000ULL)
 | 
			
		||||
		x.i &= DOUBLE_SIGN;  // turn into signed zero
 | 
			
		||||
	return x.d;
 | 
			
		||||
    IntDouble x; x.d = d;
 | 
			
		||||
    if ((x.i & DOUBLE_EXP) < 0x3800000000000000ULL)
 | 
			
		||||
        x.i &= DOUBLE_SIGN;  // turn into signed zero
 | 
			
		||||
    return x.d;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum PPCFpClass
 | 
			
		||||
{
 | 
			
		||||
	PPC_FPCLASS_QNAN = 0x11,
 | 
			
		||||
	PPC_FPCLASS_NINF = 0x9,
 | 
			
		||||
	PPC_FPCLASS_NN   = 0x8,
 | 
			
		||||
	PPC_FPCLASS_ND   = 0x18,
 | 
			
		||||
	PPC_FPCLASS_NZ   = 0x12,
 | 
			
		||||
	PPC_FPCLASS_PZ   = 0x2,
 | 
			
		||||
	PPC_FPCLASS_PD   = 0x14,
 | 
			
		||||
	PPC_FPCLASS_PN   = 0x4,
 | 
			
		||||
	PPC_FPCLASS_PINF = 0x5,
 | 
			
		||||
    PPC_FPCLASS_QNAN = 0x11,
 | 
			
		||||
    PPC_FPCLASS_NINF = 0x9,
 | 
			
		||||
    PPC_FPCLASS_NN   = 0x8,
 | 
			
		||||
    PPC_FPCLASS_ND   = 0x18,
 | 
			
		||||
    PPC_FPCLASS_NZ   = 0x12,
 | 
			
		||||
    PPC_FPCLASS_PZ   = 0x2,
 | 
			
		||||
    PPC_FPCLASS_PD   = 0x14,
 | 
			
		||||
    PPC_FPCLASS_PN   = 0x4,
 | 
			
		||||
    PPC_FPCLASS_PINF = 0x5,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Uses PowerPC conventions for the return value, so it can be easily
 | 
			
		||||
@@ -93,42 +93,42 @@ u32 ClassifyFloat(float fvalue);
 | 
			
		||||
template<class T>
 | 
			
		||||
struct Rectangle
 | 
			
		||||
{
 | 
			
		||||
	T left;
 | 
			
		||||
	T top;
 | 
			
		||||
	T right;
 | 
			
		||||
	T bottom;
 | 
			
		||||
    T left;
 | 
			
		||||
    T top;
 | 
			
		||||
    T right;
 | 
			
		||||
    T bottom;
 | 
			
		||||
 | 
			
		||||
	Rectangle()
 | 
			
		||||
	{ }
 | 
			
		||||
    Rectangle()
 | 
			
		||||
    { }
 | 
			
		||||
 | 
			
		||||
	Rectangle(T theLeft, T theTop, T theRight, T theBottom)
 | 
			
		||||
		: left(theLeft), top(theTop), right(theRight), bottom(theBottom)
 | 
			
		||||
	{ }
 | 
			
		||||
	
 | 
			
		||||
	bool operator==(const Rectangle& r) { return left==r.left && top==r.top && right==r.right && bottom==r.bottom; }
 | 
			
		||||
    Rectangle(T theLeft, T theTop, T theRight, T theBottom)
 | 
			
		||||
        : left(theLeft), top(theTop), right(theRight), bottom(theBottom)
 | 
			
		||||
    { }
 | 
			
		||||
    
 | 
			
		||||
    bool operator==(const Rectangle& r) { return left==r.left && top==r.top && right==r.right && bottom==r.bottom; }
 | 
			
		||||
 | 
			
		||||
	T GetWidth() const { return abs(right - left); }
 | 
			
		||||
	T GetHeight() const { return abs(bottom - top); }
 | 
			
		||||
    T GetWidth() const { return abs(right - left); }
 | 
			
		||||
    T GetHeight() const { return abs(bottom - top); }
 | 
			
		||||
 | 
			
		||||
	// If the rectangle is in a coordinate system with a lower-left origin, use
 | 
			
		||||
	// this Clamp.
 | 
			
		||||
	void ClampLL(T x1, T y1, T x2, T y2)
 | 
			
		||||
	{
 | 
			
		||||
		if (left < x1) left = x1;
 | 
			
		||||
		if (right > x2) right = x2;
 | 
			
		||||
		if (top > y1) top = y1;
 | 
			
		||||
		if (bottom < y2) bottom = y2;
 | 
			
		||||
	}
 | 
			
		||||
    // If the rectangle is in a coordinate system with a lower-left origin, use
 | 
			
		||||
    // this Clamp.
 | 
			
		||||
    void ClampLL(T x1, T y1, T x2, T y2)
 | 
			
		||||
    {
 | 
			
		||||
        if (left < x1) left = x1;
 | 
			
		||||
        if (right > x2) right = x2;
 | 
			
		||||
        if (top > y1) top = y1;
 | 
			
		||||
        if (bottom < y2) bottom = y2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// If the rectangle is in a coordinate system with an upper-left origin,
 | 
			
		||||
	// use this Clamp.
 | 
			
		||||
	void ClampUL(T x1, T y1, T x2, T y2) 
 | 
			
		||||
	{
 | 
			
		||||
		if (left < x1) left = x1;
 | 
			
		||||
		if (right > x2) right = x2;
 | 
			
		||||
		if (top < y1) top = y1;
 | 
			
		||||
		if (bottom > y2) bottom = y2;
 | 
			
		||||
	}
 | 
			
		||||
    // If the rectangle is in a coordinate system with an upper-left origin,
 | 
			
		||||
    // use this Clamp.
 | 
			
		||||
    void ClampUL(T x1, T y1, T x2, T y2) 
 | 
			
		||||
    {
 | 
			
		||||
        if (left < x1) left = x1;
 | 
			
		||||
        if (right > x2) right = x2;
 | 
			
		||||
        if (top < y1) top = y1;
 | 
			
		||||
        if (bottom > y2) bottom = y2;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace MathUtil
 | 
			
		||||
@@ -138,28 +138,28 @@ inline double pow2(double x) {return x * x;}
 | 
			
		||||
 | 
			
		||||
float MathFloatVectorSum(const std::vector<float>&);
 | 
			
		||||
 | 
			
		||||
#define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1))
 | 
			
		||||
#define ROUND_DOWN(x, a)	((x) & ~((a) - 1))
 | 
			
		||||
#define ROUND_UP(x, a)        (((x) + (a) - 1) & ~((a) - 1))
 | 
			
		||||
#define ROUND_DOWN(x, a)    ((x) & ~((a) - 1))
 | 
			
		||||
 | 
			
		||||
// Rounds down. 0 -> undefined
 | 
			
		||||
inline u64 Log2(u64 val)
 | 
			
		||||
{
 | 
			
		||||
#if defined(__GNUC__)
 | 
			
		||||
	return 63 - __builtin_clzll(val);
 | 
			
		||||
    return 63 - __builtin_clzll(val);
 | 
			
		||||
 | 
			
		||||
#elif defined(_MSC_VER) && defined(_M_X64)
 | 
			
		||||
	unsigned long result = -1;
 | 
			
		||||
	_BitScanReverse64(&result, val);
 | 
			
		||||
	return result;
 | 
			
		||||
    unsigned long result = -1;
 | 
			
		||||
    _BitScanReverse64(&result, val);
 | 
			
		||||
    return result;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
	u64 result = -1;
 | 
			
		||||
	while (val != 0)
 | 
			
		||||
	{
 | 
			
		||||
		val >>= 1;
 | 
			
		||||
		++result;
 | 
			
		||||
	}
 | 
			
		||||
	return result;
 | 
			
		||||
    u64 result = -1;
 | 
			
		||||
    while (val != 0)
 | 
			
		||||
    {
 | 
			
		||||
        val >>= 1;
 | 
			
		||||
        ++result;
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -169,32 +169,32 @@ inline u64 Log2(u64 val)
 | 
			
		||||
class Matrix33
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	static void LoadIdentity(Matrix33 &mtx);
 | 
			
		||||
    static void LoadIdentity(Matrix33 &mtx);
 | 
			
		||||
 | 
			
		||||
	// set mtx to be a rotation matrix around the x axis
 | 
			
		||||
	static void RotateX(Matrix33 &mtx, float rad);
 | 
			
		||||
	// set mtx to be a rotation matrix around the y axis
 | 
			
		||||
	static void RotateY(Matrix33 &mtx, float rad);
 | 
			
		||||
    // set mtx to be a rotation matrix around the x axis
 | 
			
		||||
    static void RotateX(Matrix33 &mtx, float rad);
 | 
			
		||||
    // set mtx to be a rotation matrix around the y axis
 | 
			
		||||
    static void RotateY(Matrix33 &mtx, float rad);
 | 
			
		||||
 | 
			
		||||
	// set result = a x b
 | 
			
		||||
	static void Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result);
 | 
			
		||||
	static void Multiply(const Matrix33 &a, const float vec[3], float result[3]);
 | 
			
		||||
    // set result = a x b
 | 
			
		||||
    static void Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result);
 | 
			
		||||
    static void Multiply(const Matrix33 &a, const float vec[3], float result[3]);
 | 
			
		||||
 | 
			
		||||
	float data[9];
 | 
			
		||||
    float data[9];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Matrix44
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	static void LoadIdentity(Matrix44 &mtx);
 | 
			
		||||
	static void LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33);
 | 
			
		||||
	static void Set(Matrix44 &mtx, const float mtxArray[16]);
 | 
			
		||||
    static void LoadIdentity(Matrix44 &mtx);
 | 
			
		||||
    static void LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33);
 | 
			
		||||
    static void Set(Matrix44 &mtx, const float mtxArray[16]);
 | 
			
		||||
 | 
			
		||||
	static void Translate(Matrix44 &mtx, const float vec[3]);
 | 
			
		||||
    static void Translate(Matrix44 &mtx, const float vec[3]);
 | 
			
		||||
 | 
			
		||||
	static void Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result);
 | 
			
		||||
    static void Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result);
 | 
			
		||||
 | 
			
		||||
	float data[16];
 | 
			
		||||
    float data[16];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _MATH_UTIL_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -27,148 +27,148 @@
 | 
			
		||||
void* AllocateExecutableMemory(size_t size, bool low)
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
	void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 | 
			
		||||
    void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 | 
			
		||||
#else
 | 
			
		||||
	static char *map_hint = 0;
 | 
			
		||||
    static char *map_hint = 0;
 | 
			
		||||
#if defined(__x86_64__) && !defined(MAP_32BIT)
 | 
			
		||||
	// This OS has no flag to enforce allocation below the 4 GB boundary,
 | 
			
		||||
	// but if we hint that we want a low address it is very likely we will
 | 
			
		||||
	// get one.
 | 
			
		||||
	// An older version of this code used MAP_FIXED, but that has the side
 | 
			
		||||
	// effect of discarding already mapped pages that happen to be in the
 | 
			
		||||
	// requested virtual memory range (such as the emulated RAM, sometimes).
 | 
			
		||||
	if (low && (!map_hint))
 | 
			
		||||
		map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */
 | 
			
		||||
    // This OS has no flag to enforce allocation below the 4 GB boundary,
 | 
			
		||||
    // but if we hint that we want a low address it is very likely we will
 | 
			
		||||
    // get one.
 | 
			
		||||
    // An older version of this code used MAP_FIXED, but that has the side
 | 
			
		||||
    // effect of discarding already mapped pages that happen to be in the
 | 
			
		||||
    // requested virtual memory range (such as the emulated RAM, sometimes).
 | 
			
		||||
    if (low && (!map_hint))
 | 
			
		||||
        map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */
 | 
			
		||||
#endif
 | 
			
		||||
	void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
 | 
			
		||||
		MAP_ANON | MAP_PRIVATE
 | 
			
		||||
    void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
 | 
			
		||||
        MAP_ANON | MAP_PRIVATE
 | 
			
		||||
#if defined(__x86_64__) && defined(MAP_32BIT)
 | 
			
		||||
		| (low ? MAP_32BIT : 0)
 | 
			
		||||
        | (low ? MAP_32BIT : 0)
 | 
			
		||||
#endif
 | 
			
		||||
		, -1, 0);
 | 
			
		||||
        , -1, 0);
 | 
			
		||||
#endif /* defined(_WIN32) */
 | 
			
		||||
 | 
			
		||||
	// printf("Mapped executable memory at %p (size %ld)\n", ptr,
 | 
			
		||||
	//	(unsigned long)size);
 | 
			
		||||
	
 | 
			
		||||
    // printf("Mapped executable memory at %p (size %ld)\n", ptr,
 | 
			
		||||
    //    (unsigned long)size);
 | 
			
		||||
    
 | 
			
		||||
#if defined(__FreeBSD__)
 | 
			
		||||
	if (ptr == MAP_FAILED)
 | 
			
		||||
	{
 | 
			
		||||
		ptr = NULL;
 | 
			
		||||
    if (ptr == MAP_FAILED)
 | 
			
		||||
    {
 | 
			
		||||
        ptr = NULL;
 | 
			
		||||
#else
 | 
			
		||||
	if (ptr == NULL)
 | 
			
		||||
	{
 | 
			
		||||
#endif	
 | 
			
		||||
		PanicAlert("Failed to allocate executable memory");
 | 
			
		||||
	}
 | 
			
		||||
    if (ptr == NULL)
 | 
			
		||||
    {
 | 
			
		||||
#endif    
 | 
			
		||||
        PanicAlert("Failed to allocate executable memory");
 | 
			
		||||
    }
 | 
			
		||||
#if !defined(_WIN32) && defined(__x86_64__) && !defined(MAP_32BIT)
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (low)
 | 
			
		||||
		{
 | 
			
		||||
			map_hint += size;
 | 
			
		||||
			map_hint = (char*)round_page(map_hint); /* round up to the next page */
 | 
			
		||||
			// printf("Next map will (hopefully) be at %p\n", map_hint);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        if (low)
 | 
			
		||||
        {
 | 
			
		||||
            map_hint += size;
 | 
			
		||||
            map_hint = (char*)round_page(map_hint); /* round up to the next page */
 | 
			
		||||
            // printf("Next map will (hopefully) be at %p\n", map_hint);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_M_X64)
 | 
			
		||||
	if ((u64)ptr >= 0x80000000 && low == true)
 | 
			
		||||
		PanicAlert("Executable memory ended up above 2GB!");
 | 
			
		||||
    if ((u64)ptr >= 0x80000000 && low == true)
 | 
			
		||||
        PanicAlert("Executable memory ended up above 2GB!");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return ptr;
 | 
			
		||||
    return ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void* AllocateMemoryPages(size_t size)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
 | 
			
		||||
    void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
 | 
			
		||||
#else
 | 
			
		||||
	void* ptr = mmap(0, size, PROT_READ | PROT_WRITE,
 | 
			
		||||
			MAP_ANON | MAP_PRIVATE, -1, 0);
 | 
			
		||||
    void* ptr = mmap(0, size, PROT_READ | PROT_WRITE,
 | 
			
		||||
            MAP_ANON | MAP_PRIVATE, -1, 0);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	// printf("Mapped memory at %p (size %ld)\n", ptr,
 | 
			
		||||
	//	(unsigned long)size);
 | 
			
		||||
    // printf("Mapped memory at %p (size %ld)\n", ptr,
 | 
			
		||||
    //    (unsigned long)size);
 | 
			
		||||
 | 
			
		||||
	if (ptr == NULL)
 | 
			
		||||
		PanicAlert("Failed to allocate raw memory");
 | 
			
		||||
    if (ptr == NULL)
 | 
			
		||||
        PanicAlert("Failed to allocate raw memory");
 | 
			
		||||
 | 
			
		||||
	return ptr;
 | 
			
		||||
    return ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void* AllocateAlignedMemory(size_t size,size_t alignment)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	void* ptr =  _aligned_malloc(size,alignment);
 | 
			
		||||
    void* ptr =  _aligned_malloc(size,alignment);
 | 
			
		||||
#else
 | 
			
		||||
	void* ptr = NULL;
 | 
			
		||||
    void* ptr = NULL;
 | 
			
		||||
#ifdef ANDROID
 | 
			
		||||
	ptr = memalign(alignment, size);
 | 
			
		||||
    ptr = memalign(alignment, size);
 | 
			
		||||
#else
 | 
			
		||||
	if (posix_memalign(&ptr, alignment, size) != 0)
 | 
			
		||||
		ERROR_LOG(MEMMAP, "Failed to allocate aligned memory");
 | 
			
		||||
    if (posix_memalign(&ptr, alignment, size) != 0)
 | 
			
		||||
        ERROR_LOG(MEMMAP, "Failed to allocate aligned memory");
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	// printf("Mapped memory at %p (size %ld)\n", ptr,
 | 
			
		||||
	//	(unsigned long)size);
 | 
			
		||||
    // printf("Mapped memory at %p (size %ld)\n", ptr,
 | 
			
		||||
    //    (unsigned long)size);
 | 
			
		||||
 | 
			
		||||
	if (ptr == NULL)
 | 
			
		||||
		PanicAlert("Failed to allocate aligned memory");
 | 
			
		||||
    if (ptr == NULL)
 | 
			
		||||
        PanicAlert("Failed to allocate aligned memory");
 | 
			
		||||
 | 
			
		||||
	return ptr;
 | 
			
		||||
    return ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FreeMemoryPages(void* ptr, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (ptr)
 | 
			
		||||
	{
 | 
			
		||||
    if (ptr)
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	
 | 
			
		||||
		if (!VirtualFree(ptr, 0, MEM_RELEASE))
 | 
			
		||||
			PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg());
 | 
			
		||||
		ptr = NULL; // Is this our responsibility?
 | 
			
		||||
	
 | 
			
		||||
    
 | 
			
		||||
        if (!VirtualFree(ptr, 0, MEM_RELEASE))
 | 
			
		||||
            PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg());
 | 
			
		||||
        ptr = NULL; // Is this our responsibility?
 | 
			
		||||
    
 | 
			
		||||
#else
 | 
			
		||||
		munmap(ptr, size);
 | 
			
		||||
        munmap(ptr, size);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FreeAlignedMemory(void* ptr)
 | 
			
		||||
{
 | 
			
		||||
	if (ptr)
 | 
			
		||||
	{
 | 
			
		||||
    if (ptr)
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	_aligned_free(ptr);
 | 
			
		||||
    _aligned_free(ptr);
 | 
			
		||||
#else
 | 
			
		||||
	free(ptr);
 | 
			
		||||
    free(ptr);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WriteProtectMemory(void* ptr, size_t size, bool allowExecute)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	DWORD oldValue;
 | 
			
		||||
	if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
 | 
			
		||||
		PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg());
 | 
			
		||||
    DWORD oldValue;
 | 
			
		||||
    if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
 | 
			
		||||
        PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg());
 | 
			
		||||
#else
 | 
			
		||||
	mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ);
 | 
			
		||||
    mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	DWORD oldValue;
 | 
			
		||||
	if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue))
 | 
			
		||||
		PanicAlert("UnWriteProtectMemory failed!\n%s", GetLastErrorMsg());
 | 
			
		||||
    DWORD oldValue;
 | 
			
		||||
    if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue))
 | 
			
		||||
        PanicAlert("UnWriteProtectMemory failed!\n%s", GetLastErrorMsg());
 | 
			
		||||
#else
 | 
			
		||||
	mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ);
 | 
			
		||||
    mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -176,22 +176,22 @@ std::string MemUsage()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#pragma comment(lib, "psapi")
 | 
			
		||||
	DWORD processID = GetCurrentProcessId();
 | 
			
		||||
	HANDLE hProcess;
 | 
			
		||||
	PROCESS_MEMORY_COUNTERS pmc;
 | 
			
		||||
	std::string Ret;
 | 
			
		||||
    DWORD processID = GetCurrentProcessId();
 | 
			
		||||
    HANDLE hProcess;
 | 
			
		||||
    PROCESS_MEMORY_COUNTERS pmc;
 | 
			
		||||
    std::string Ret;
 | 
			
		||||
 | 
			
		||||
	// Print information about the memory usage of the process.
 | 
			
		||||
    // Print information about the memory usage of the process.
 | 
			
		||||
 | 
			
		||||
	hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
 | 
			
		||||
	if (NULL == hProcess) return "MemUsage Error";
 | 
			
		||||
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
 | 
			
		||||
    if (NULL == hProcess) return "MemUsage Error";
 | 
			
		||||
 | 
			
		||||
	if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
 | 
			
		||||
		Ret = StringFromFormat("%s K", ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str());
 | 
			
		||||
    if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
 | 
			
		||||
        Ret = StringFromFormat("%s K", ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str());
 | 
			
		||||
 | 
			
		||||
	CloseHandle(hProcess);
 | 
			
		||||
	return Ret;
 | 
			
		||||
    CloseHandle(hProcess);
 | 
			
		||||
    return Ret;
 | 
			
		||||
#else
 | 
			
		||||
	return "";
 | 
			
		||||
    return "";
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,20 +18,20 @@
 | 
			
		||||
// This function might change the error code.
 | 
			
		||||
const char* GetLastErrorMsg()
 | 
			
		||||
{
 | 
			
		||||
	static const size_t buff_size = 255;
 | 
			
		||||
    static const size_t buff_size = 255;
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	static __declspec(thread) char err_str[buff_size] = {};
 | 
			
		||||
    static __declspec(thread) char err_str[buff_size] = {};
 | 
			
		||||
 | 
			
		||||
	FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
 | 
			
		||||
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
 | 
			
		||||
		err_str, buff_size, NULL);
 | 
			
		||||
    FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
 | 
			
		||||
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
 | 
			
		||||
        err_str, buff_size, NULL);
 | 
			
		||||
#else
 | 
			
		||||
	static __thread char err_str[buff_size] = {};
 | 
			
		||||
    static __thread char err_str[buff_size] = {};
 | 
			
		||||
 | 
			
		||||
	// Thread safe (XSI-compliant)
 | 
			
		||||
	strerror_r(errno, err_str, buff_size);
 | 
			
		||||
    // Thread safe (XSI-compliant)
 | 
			
		||||
    strerror_r(errno, err_str, buff_size);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return err_str;
 | 
			
		||||
    return err_str;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,90 +18,90 @@ static StringTranslator str_translator = DefaultStringTranslator;
 | 
			
		||||
// wxWidgets is enabled we will use wxMsgAlert() that is defined in Main.cpp
 | 
			
		||||
void RegisterMsgAlertHandler(MsgAlertHandler handler)
 | 
			
		||||
{
 | 
			
		||||
	msg_handler = handler;
 | 
			
		||||
    msg_handler = handler;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Select translation function.  For wxWidgets use wxStringTranslator in Main.cpp
 | 
			
		||||
void RegisterStringTranslator(StringTranslator translator)
 | 
			
		||||
{
 | 
			
		||||
	str_translator = translator;
 | 
			
		||||
    str_translator = translator;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// enable/disable the alert handler
 | 
			
		||||
void SetEnableAlert(bool enable)
 | 
			
		||||
{
 | 
			
		||||
	AlertEnabled = enable;
 | 
			
		||||
    AlertEnabled = enable;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This is the first stop for gui alerts where the log is updated and the
 | 
			
		||||
// correct window is shown
 | 
			
		||||
bool MsgAlert(bool yes_no, int Style, const char* format, ...)
 | 
			
		||||
{
 | 
			
		||||
	// Read message and write it to the log
 | 
			
		||||
	std::string caption;
 | 
			
		||||
	char buffer[2048];
 | 
			
		||||
    // Read message and write it to the log
 | 
			
		||||
    std::string caption;
 | 
			
		||||
    char buffer[2048];
 | 
			
		||||
 | 
			
		||||
	static std::string info_caption;
 | 
			
		||||
	static std::string warn_caption;
 | 
			
		||||
	static std::string ques_caption;
 | 
			
		||||
	static std::string crit_caption;
 | 
			
		||||
    static std::string info_caption;
 | 
			
		||||
    static std::string warn_caption;
 | 
			
		||||
    static std::string ques_caption;
 | 
			
		||||
    static std::string crit_caption;
 | 
			
		||||
 | 
			
		||||
	if (!info_caption.length())
 | 
			
		||||
	{
 | 
			
		||||
		info_caption = str_translator(_trans("Information"));
 | 
			
		||||
		ques_caption = str_translator(_trans("Question"));
 | 
			
		||||
		warn_caption = str_translator(_trans("Warning"));
 | 
			
		||||
		crit_caption = str_translator(_trans("Critical"));
 | 
			
		||||
	}
 | 
			
		||||
    if (!info_caption.length())
 | 
			
		||||
    {
 | 
			
		||||
        info_caption = str_translator(_trans("Information"));
 | 
			
		||||
        ques_caption = str_translator(_trans("Question"));
 | 
			
		||||
        warn_caption = str_translator(_trans("Warning"));
 | 
			
		||||
        crit_caption = str_translator(_trans("Critical"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	switch(Style)
 | 
			
		||||
	{
 | 
			
		||||
		case INFORMATION:
 | 
			
		||||
			caption = info_caption;
 | 
			
		||||
			break;
 | 
			
		||||
		case QUESTION:
 | 
			
		||||
			caption = ques_caption;
 | 
			
		||||
			break;
 | 
			
		||||
		case WARNING:
 | 
			
		||||
			caption = warn_caption;
 | 
			
		||||
			break;
 | 
			
		||||
		case CRITICAL:
 | 
			
		||||
			caption = crit_caption;
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
    switch(Style)
 | 
			
		||||
    {
 | 
			
		||||
        case INFORMATION:
 | 
			
		||||
            caption = info_caption;
 | 
			
		||||
            break;
 | 
			
		||||
        case QUESTION:
 | 
			
		||||
            caption = ques_caption;
 | 
			
		||||
            break;
 | 
			
		||||
        case WARNING:
 | 
			
		||||
            caption = warn_caption;
 | 
			
		||||
            break;
 | 
			
		||||
        case CRITICAL:
 | 
			
		||||
            caption = crit_caption;
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	va_list args;
 | 
			
		||||
	va_start(args, format);
 | 
			
		||||
	CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args);
 | 
			
		||||
	va_end(args);
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start(args, format);
 | 
			
		||||
    CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
 | 
			
		||||
	ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer);
 | 
			
		||||
    ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer);
 | 
			
		||||
 | 
			
		||||
	// Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored
 | 
			
		||||
	if (msg_handler && (AlertEnabled || Style == QUESTION || Style == CRITICAL))
 | 
			
		||||
		return msg_handler(caption.c_str(), buffer, yes_no, Style);
 | 
			
		||||
    // Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored
 | 
			
		||||
    if (msg_handler && (AlertEnabled || Style == QUESTION || Style == CRITICAL))
 | 
			
		||||
        return msg_handler(caption.c_str(), buffer, yes_no, Style);
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Default non library dependent panic alert
 | 
			
		||||
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style)
 | 
			
		||||
{
 | 
			
		||||
//#ifdef _WIN32
 | 
			
		||||
//	int STYLE = MB_ICONINFORMATION;
 | 
			
		||||
//	if (Style == QUESTION) STYLE = MB_ICONQUESTION;
 | 
			
		||||
//	if (Style == WARNING) STYLE = MB_ICONWARNING;
 | 
			
		||||
//    int STYLE = MB_ICONINFORMATION;
 | 
			
		||||
//    if (Style == QUESTION) STYLE = MB_ICONQUESTION;
 | 
			
		||||
//    if (Style == WARNING) STYLE = MB_ICONWARNING;
 | 
			
		||||
//
 | 
			
		||||
//	return IDYES == MessageBox(0, UTF8ToTStr(text).c_str(), UTF8ToTStr(caption).c_str(), STYLE | (yes_no ? MB_YESNO : MB_OK));
 | 
			
		||||
//    return IDYES == MessageBox(0, UTF8ToTStr(text).c_str(), UTF8ToTStr(caption).c_str(), STYLE | (yes_no ? MB_YESNO : MB_OK));
 | 
			
		||||
//#else
 | 
			
		||||
	printf("%s\n", text);
 | 
			
		||||
	return true;
 | 
			
		||||
    printf("%s\n", text);
 | 
			
		||||
    return true;
 | 
			
		||||
//#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Default (non) translator
 | 
			
		||||
std::string DefaultStringTranslator(const char* text)
 | 
			
		||||
{
 | 
			
		||||
	return text;
 | 
			
		||||
    return text;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,10 +10,10 @@
 | 
			
		||||
// Message alerts
 | 
			
		||||
enum MSG_TYPE
 | 
			
		||||
{
 | 
			
		||||
	INFORMATION,
 | 
			
		||||
	QUESTION,
 | 
			
		||||
	WARNING,
 | 
			
		||||
	CRITICAL
 | 
			
		||||
    INFORMATION,
 | 
			
		||||
    QUESTION,
 | 
			
		||||
    WARNING,
 | 
			
		||||
    CRITICAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef bool (*MsgAlertHandler)(const char* caption, const char* text, 
 | 
			
		||||
@@ -25,49 +25,49 @@ void RegisterStringTranslator(StringTranslator translator);
 | 
			
		||||
 | 
			
		||||
extern bool MsgAlert(bool yes_no, int Style, const char* format, ...)
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
	__attribute__((format(printf, 3, 4)))
 | 
			
		||||
    __attribute__((format(printf, 3, 4)))
 | 
			
		||||
#endif
 | 
			
		||||
	;
 | 
			
		||||
    ;
 | 
			
		||||
void SetEnableAlert(bool enable);
 | 
			
		||||
 | 
			
		||||
#ifndef GEKKO
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	#define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__) 
 | 
			
		||||
	#define PanicAlert(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__) 
 | 
			
		||||
	#define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__) 
 | 
			
		||||
	#define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__) 
 | 
			
		||||
	#define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__) 
 | 
			
		||||
	// Use these macros (that do the same thing) if the message should be translated.
 | 
			
		||||
	#define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__) 
 | 
			
		||||
	#define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__) 
 | 
			
		||||
	#define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__) 
 | 
			
		||||
	#define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__) 
 | 
			
		||||
	#define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__) 
 | 
			
		||||
    #define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__) 
 | 
			
		||||
    #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__) 
 | 
			
		||||
    #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__) 
 | 
			
		||||
    #define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__) 
 | 
			
		||||
    #define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__) 
 | 
			
		||||
    // Use these macros (that do the same thing) if the message should be translated.
 | 
			
		||||
    #define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__) 
 | 
			
		||||
    #define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__) 
 | 
			
		||||
    #define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__) 
 | 
			
		||||
    #define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__) 
 | 
			
		||||
    #define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__) 
 | 
			
		||||
#else
 | 
			
		||||
	#define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__) 
 | 
			
		||||
	#define PanicAlert(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__) 
 | 
			
		||||
	#define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__) 
 | 
			
		||||
	#define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__) 
 | 
			
		||||
	#define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__) 
 | 
			
		||||
	// Use these macros (that do the same thing) if the message should be translated.
 | 
			
		||||
	#define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__) 
 | 
			
		||||
	#define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__) 
 | 
			
		||||
	#define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__) 
 | 
			
		||||
	#define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__) 
 | 
			
		||||
	#define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__) 
 | 
			
		||||
    #define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__) 
 | 
			
		||||
    #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__) 
 | 
			
		||||
    #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__) 
 | 
			
		||||
    #define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__) 
 | 
			
		||||
    #define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__) 
 | 
			
		||||
    // Use these macros (that do the same thing) if the message should be translated.
 | 
			
		||||
    #define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__) 
 | 
			
		||||
    #define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__) 
 | 
			
		||||
    #define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__) 
 | 
			
		||||
    #define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__) 
 | 
			
		||||
    #define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__) 
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
// GEKKO
 | 
			
		||||
	#define SuccessAlert(format, ...) ;
 | 
			
		||||
	#define PanicAlert(format, ...) ;
 | 
			
		||||
	#define PanicYesNo(format, ...) ;
 | 
			
		||||
	#define AskYesNo(format, ...) ;
 | 
			
		||||
	#define CriticalAlert(format, ...) ;
 | 
			
		||||
	#define SuccessAlertT(format, ...) ;
 | 
			
		||||
	#define PanicAlertT(format, ...) ;
 | 
			
		||||
	#define PanicYesNoT(format, ...) ;
 | 
			
		||||
	#define AskYesNoT(format, ...) ;
 | 
			
		||||
	#define CriticalAlertT(format, ...) ;
 | 
			
		||||
    #define SuccessAlert(format, ...) ;
 | 
			
		||||
    #define PanicAlert(format, ...) ;
 | 
			
		||||
    #define PanicYesNo(format, ...) ;
 | 
			
		||||
    #define AskYesNo(format, ...) ;
 | 
			
		||||
    #define CriticalAlert(format, ...) ;
 | 
			
		||||
    #define SuccessAlertT(format, ...) ;
 | 
			
		||||
    #define PanicAlertT(format, ...) ;
 | 
			
		||||
    #define PanicYesNoT(format, ...) ;
 | 
			
		||||
    #define AskYesNoT(format, ...) ;
 | 
			
		||||
    #define CriticalAlertT(format, ...) ;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // _MSGHANDLER_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -76,9 +76,9 @@
 | 
			
		||||
#define EMU_FASTCALL __fastcall
 | 
			
		||||
 | 
			
		||||
inline struct tm* localtime_r(const time_t *clock, struct tm *result) {
 | 
			
		||||
	if (localtime_s(result, clock) == 0)
 | 
			
		||||
		return result;
 | 
			
		||||
	return NULL;
 | 
			
		||||
    if (localtime_s(result, clock) == 0)
 | 
			
		||||
        return result;
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
#ifndef CONDITION_VARIABLE_H_
 | 
			
		||||
#define CONDITION_VARIABLE_H_
 | 
			
		||||
 | 
			
		||||
#define GCC_VER(x,y,z)	((x) * 10000 + (y) * 100 + (z))
 | 
			
		||||
#define GCC_VER(x,y,z)    ((x) * 10000 + (y) * 100 + (z))
 | 
			
		||||
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
 | 
			
		||||
 | 
			
		||||
#ifndef __has_include
 | 
			
		||||
@@ -47,121 +47,121 @@ namespace std
 | 
			
		||||
class condition_variable
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
	typedef CONDITION_VARIABLE native_type;
 | 
			
		||||
    typedef CONDITION_VARIABLE native_type;
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
	typedef HANDLE native_type;
 | 
			
		||||
    typedef HANDLE native_type;
 | 
			
		||||
#else
 | 
			
		||||
	typedef pthread_cond_t native_type;
 | 
			
		||||
    typedef pthread_cond_t native_type;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
#ifdef USE_EVENTS
 | 
			
		||||
	typedef native_type native_handle_type;
 | 
			
		||||
    typedef native_type native_handle_type;
 | 
			
		||||
#else
 | 
			
		||||
	typedef native_type* native_handle_type;
 | 
			
		||||
    typedef native_type* native_handle_type;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	condition_variable()
 | 
			
		||||
	{
 | 
			
		||||
    condition_variable()
 | 
			
		||||
    {
 | 
			
		||||
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
		InitializeConditionVariable(&m_handle);
 | 
			
		||||
        InitializeConditionVariable(&m_handle);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
		m_handle = CreateEvent(NULL, false, false, NULL);
 | 
			
		||||
        m_handle = CreateEvent(NULL, false, false, NULL);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_cond_init(&m_handle, NULL);
 | 
			
		||||
        pthread_cond_init(&m_handle, NULL);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	~condition_variable()
 | 
			
		||||
	{
 | 
			
		||||
    ~condition_variable()
 | 
			
		||||
    {
 | 
			
		||||
#if defined(_WIN32) && !defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
		CloseHandle(m_handle);
 | 
			
		||||
        CloseHandle(m_handle);
 | 
			
		||||
#elif !defined(_WIN32)
 | 
			
		||||
		pthread_cond_destroy(&m_handle);
 | 
			
		||||
        pthread_cond_destroy(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	condition_variable(const condition_variable&) /*= delete*/;
 | 
			
		||||
	condition_variable& operator=(const condition_variable&) /*= delete*/;
 | 
			
		||||
    condition_variable(const condition_variable&) /*= delete*/;
 | 
			
		||||
    condition_variable& operator=(const condition_variable&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
	void notify_one()
 | 
			
		||||
	{
 | 
			
		||||
    void notify_one()
 | 
			
		||||
    {
 | 
			
		||||
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
		WakeConditionVariable(&m_handle);
 | 
			
		||||
        WakeConditionVariable(&m_handle);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
		SetEvent(m_handle);
 | 
			
		||||
        SetEvent(m_handle);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_cond_signal(&m_handle);
 | 
			
		||||
        pthread_cond_signal(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void notify_all()
 | 
			
		||||
	{
 | 
			
		||||
    void notify_all()
 | 
			
		||||
    {
 | 
			
		||||
#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
		WakeAllConditionVariable(&m_handle);
 | 
			
		||||
        WakeAllConditionVariable(&m_handle);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
		// TODO: broken
 | 
			
		||||
		SetEvent(m_handle);
 | 
			
		||||
        // TODO: broken
 | 
			
		||||
        SetEvent(m_handle);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_cond_broadcast(&m_handle);
 | 
			
		||||
        pthread_cond_broadcast(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void wait(unique_lock<mutex>& lock)
 | 
			
		||||
	{
 | 
			
		||||
    void wait(unique_lock<mutex>& lock)
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	#ifdef USE_SRWLOCKS
 | 
			
		||||
		SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0);
 | 
			
		||||
	#elif defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
		SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE);
 | 
			
		||||
	#else
 | 
			
		||||
		// TODO: broken, the unlock and wait need to be atomic
 | 
			
		||||
		lock.unlock();
 | 
			
		||||
		WaitForSingleObject(m_handle, INFINITE);
 | 
			
		||||
		lock.lock();
 | 
			
		||||
	#endif
 | 
			
		||||
    #ifdef USE_SRWLOCKS
 | 
			
		||||
        SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0);
 | 
			
		||||
    #elif defined(USE_CONDITION_VARIABLES)
 | 
			
		||||
        SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE);
 | 
			
		||||
    #else
 | 
			
		||||
        // TODO: broken, the unlock and wait need to be atomic
 | 
			
		||||
        lock.unlock();
 | 
			
		||||
        WaitForSingleObject(m_handle, INFINITE);
 | 
			
		||||
        lock.lock();
 | 
			
		||||
    #endif
 | 
			
		||||
#else
 | 
			
		||||
		pthread_cond_wait(&m_handle, lock.mutex()->native_handle());
 | 
			
		||||
        pthread_cond_wait(&m_handle, lock.mutex()->native_handle());
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	template <class Predicate>
 | 
			
		||||
	void wait(unique_lock<mutex>& lock, Predicate pred)
 | 
			
		||||
	{
 | 
			
		||||
		while (!pred())
 | 
			
		||||
			wait(lock);
 | 
			
		||||
	}
 | 
			
		||||
    template <class Predicate>
 | 
			
		||||
    void wait(unique_lock<mutex>& lock, Predicate pred)
 | 
			
		||||
    {
 | 
			
		||||
        while (!pred())
 | 
			
		||||
            wait(lock);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	//template <class Clock, class Duration>
 | 
			
		||||
	//cv_status wait_until(unique_lock<mutex>& lock,
 | 
			
		||||
	//	const chrono::time_point<Clock, Duration>& abs_time);
 | 
			
		||||
    //template <class Clock, class Duration>
 | 
			
		||||
    //cv_status wait_until(unique_lock<mutex>& lock,
 | 
			
		||||
    //    const chrono::time_point<Clock, Duration>& abs_time);
 | 
			
		||||
 | 
			
		||||
	//template <class Clock, class Duration, class Predicate>
 | 
			
		||||
	//	bool wait_until(unique_lock<mutex>& lock,
 | 
			
		||||
	//	const chrono::time_point<Clock, Duration>& abs_time,
 | 
			
		||||
	//	Predicate pred);
 | 
			
		||||
    //template <class Clock, class Duration, class Predicate>
 | 
			
		||||
    //    bool wait_until(unique_lock<mutex>& lock,
 | 
			
		||||
    //    const chrono::time_point<Clock, Duration>& abs_time,
 | 
			
		||||
    //    Predicate pred);
 | 
			
		||||
 | 
			
		||||
	//template <class Rep, class Period>
 | 
			
		||||
	//cv_status wait_for(unique_lock<mutex>& lock,
 | 
			
		||||
	//	const chrono::duration<Rep, Period>& rel_time);
 | 
			
		||||
    //template <class Rep, class Period>
 | 
			
		||||
    //cv_status wait_for(unique_lock<mutex>& lock,
 | 
			
		||||
    //    const chrono::duration<Rep, Period>& rel_time);
 | 
			
		||||
 | 
			
		||||
	//template <class Rep, class Period, class Predicate>
 | 
			
		||||
	//	bool wait_for(unique_lock<mutex>& lock,
 | 
			
		||||
	//	const chrono::duration<Rep, Period>& rel_time,
 | 
			
		||||
	//	Predicate pred);
 | 
			
		||||
    //template <class Rep, class Period, class Predicate>
 | 
			
		||||
    //    bool wait_for(unique_lock<mutex>& lock,
 | 
			
		||||
    //    const chrono::duration<Rep, Period>& rel_time,
 | 
			
		||||
    //    Predicate pred);
 | 
			
		||||
 | 
			
		||||
	native_handle_type native_handle()
 | 
			
		||||
	{
 | 
			
		||||
    native_handle_type native_handle()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef USE_EVENTS
 | 
			
		||||
		return m_handle;
 | 
			
		||||
        return m_handle;
 | 
			
		||||
#else
 | 
			
		||||
		return &m_handle;
 | 
			
		||||
        return &m_handle;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	native_type m_handle;
 | 
			
		||||
    native_type m_handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
#ifndef MUTEX_H_
 | 
			
		||||
#define MUTEX_H_
 | 
			
		||||
 | 
			
		||||
#define GCC_VER(x,y,z)	((x) * 10000 + (y) * 100 + (z))
 | 
			
		||||
#define GCC_VER(x,y,z)    ((x) * 10000 + (y) * 100 + (z))
 | 
			
		||||
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
 | 
			
		||||
 | 
			
		||||
#ifndef __has_include
 | 
			
		||||
@@ -46,72 +46,72 @@ namespace std
 | 
			
		||||
class recursive_mutex
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	typedef CRITICAL_SECTION native_type;
 | 
			
		||||
    typedef CRITICAL_SECTION native_type;
 | 
			
		||||
#else
 | 
			
		||||
	typedef pthread_mutex_t native_type;
 | 
			
		||||
    typedef pthread_mutex_t native_type;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	typedef native_type* native_handle_type;
 | 
			
		||||
    typedef native_type* native_handle_type;
 | 
			
		||||
 | 
			
		||||
	recursive_mutex(const recursive_mutex&) /*= delete*/;
 | 
			
		||||
	recursive_mutex& operator=(const recursive_mutex&) /*= delete*/;
 | 
			
		||||
    recursive_mutex(const recursive_mutex&) /*= delete*/;
 | 
			
		||||
    recursive_mutex& operator=(const recursive_mutex&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
	recursive_mutex()
 | 
			
		||||
	{
 | 
			
		||||
    recursive_mutex()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		InitializeCriticalSection(&m_handle);
 | 
			
		||||
        InitializeCriticalSection(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_mutexattr_t attr;
 | 
			
		||||
		pthread_mutexattr_init(&attr);
 | 
			
		||||
		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
 | 
			
		||||
		pthread_mutex_init(&m_handle, &attr);
 | 
			
		||||
        pthread_mutexattr_t attr;
 | 
			
		||||
        pthread_mutexattr_init(&attr);
 | 
			
		||||
        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
 | 
			
		||||
        pthread_mutex_init(&m_handle, &attr);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	~recursive_mutex()
 | 
			
		||||
	{
 | 
			
		||||
    ~recursive_mutex()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		DeleteCriticalSection(&m_handle);
 | 
			
		||||
        DeleteCriticalSection(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_mutex_destroy(&m_handle);
 | 
			
		||||
        pthread_mutex_destroy(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void lock()
 | 
			
		||||
	{
 | 
			
		||||
    void lock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		EnterCriticalSection(&m_handle);
 | 
			
		||||
        EnterCriticalSection(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_mutex_lock(&m_handle);
 | 
			
		||||
        pthread_mutex_lock(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void unlock()
 | 
			
		||||
	{
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		LeaveCriticalSection(&m_handle);
 | 
			
		||||
        LeaveCriticalSection(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_mutex_unlock(&m_handle);
 | 
			
		||||
        pthread_mutex_unlock(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	bool try_lock()
 | 
			
		||||
	{
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		return (0 != TryEnterCriticalSection(&m_handle));
 | 
			
		||||
        return (0 != TryEnterCriticalSection(&m_handle));
 | 
			
		||||
#else
 | 
			
		||||
		return !pthread_mutex_trylock(&m_handle);
 | 
			
		||||
#endif	
 | 
			
		||||
	}
 | 
			
		||||
        return !pthread_mutex_trylock(&m_handle);
 | 
			
		||||
#endif    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	native_handle_type native_handle()
 | 
			
		||||
	{
 | 
			
		||||
		return &m_handle;
 | 
			
		||||
	}
 | 
			
		||||
    native_handle_type native_handle()
 | 
			
		||||
    {
 | 
			
		||||
        return &m_handle;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	native_type m_handle;
 | 
			
		||||
    native_type m_handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined(_WIN32) || defined(USE_SRWLOCKS)
 | 
			
		||||
@@ -119,74 +119,74 @@ private:
 | 
			
		||||
class mutex
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	typedef SRWLOCK native_type;
 | 
			
		||||
    typedef SRWLOCK native_type;
 | 
			
		||||
#else
 | 
			
		||||
	typedef pthread_mutex_t native_type;
 | 
			
		||||
    typedef pthread_mutex_t native_type;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	typedef native_type* native_handle_type;
 | 
			
		||||
    typedef native_type* native_handle_type;
 | 
			
		||||
 | 
			
		||||
	mutex(const mutex&) /*= delete*/;
 | 
			
		||||
	mutex& operator=(const mutex&) /*= delete*/;
 | 
			
		||||
    mutex(const mutex&) /*= delete*/;
 | 
			
		||||
    mutex& operator=(const mutex&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
	mutex()
 | 
			
		||||
	{
 | 
			
		||||
    mutex()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		InitializeSRWLock(&m_handle);
 | 
			
		||||
        InitializeSRWLock(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_mutex_init(&m_handle, NULL);
 | 
			
		||||
        pthread_mutex_init(&m_handle, NULL);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	~mutex()
 | 
			
		||||
	{
 | 
			
		||||
    ~mutex()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#else
 | 
			
		||||
		pthread_mutex_destroy(&m_handle);
 | 
			
		||||
        pthread_mutex_destroy(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void lock()
 | 
			
		||||
	{
 | 
			
		||||
    void lock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		AcquireSRWLockExclusive(&m_handle);
 | 
			
		||||
        AcquireSRWLockExclusive(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_mutex_lock(&m_handle);
 | 
			
		||||
        pthread_mutex_lock(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void unlock()
 | 
			
		||||
	{
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		ReleaseSRWLockExclusive(&m_handle);
 | 
			
		||||
        ReleaseSRWLockExclusive(&m_handle);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_mutex_unlock(&m_handle);
 | 
			
		||||
        pthread_mutex_unlock(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	bool try_lock()
 | 
			
		||||
	{
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		// XXX TryAcquireSRWLockExclusive requires Windows 7!
 | 
			
		||||
		// return (0 != TryAcquireSRWLockExclusive(&m_handle));
 | 
			
		||||
		return false;
 | 
			
		||||
        // XXX TryAcquireSRWLockExclusive requires Windows 7!
 | 
			
		||||
        // return (0 != TryAcquireSRWLockExclusive(&m_handle));
 | 
			
		||||
        return false;
 | 
			
		||||
#else
 | 
			
		||||
		return !pthread_mutex_trylock(&m_handle);
 | 
			
		||||
        return !pthread_mutex_trylock(&m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	native_handle_type native_handle()
 | 
			
		||||
	{
 | 
			
		||||
		return &m_handle;
 | 
			
		||||
	}
 | 
			
		||||
    native_handle_type native_handle()
 | 
			
		||||
    {
 | 
			
		||||
        return &m_handle;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	native_type m_handle;
 | 
			
		||||
    native_type m_handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
typedef recursive_mutex mutex;	// just use CriticalSections
 | 
			
		||||
typedef recursive_mutex mutex;    // just use CriticalSections
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -198,165 +198,165 @@ template <class Mutex>
 | 
			
		||||
class lock_guard
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	typedef Mutex mutex_type;
 | 
			
		||||
    typedef Mutex mutex_type;
 | 
			
		||||
 | 
			
		||||
	explicit lock_guard(mutex_type& m)
 | 
			
		||||
		: pm(m)
 | 
			
		||||
	{
 | 
			
		||||
		m.lock();
 | 
			
		||||
	}
 | 
			
		||||
    explicit lock_guard(mutex_type& m)
 | 
			
		||||
        : pm(m)
 | 
			
		||||
    {
 | 
			
		||||
        m.lock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	lock_guard(mutex_type& m, adopt_lock_t)
 | 
			
		||||
		: pm(m)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
    lock_guard(mutex_type& m, adopt_lock_t)
 | 
			
		||||
        : pm(m)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	~lock_guard()
 | 
			
		||||
	{
 | 
			
		||||
		pm.unlock();
 | 
			
		||||
	}
 | 
			
		||||
    ~lock_guard()
 | 
			
		||||
    {
 | 
			
		||||
        pm.unlock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	lock_guard(lock_guard const&) /*= delete*/;
 | 
			
		||||
	lock_guard& operator=(lock_guard const&) /*= delete*/;
 | 
			
		||||
    lock_guard(lock_guard const&) /*= delete*/;
 | 
			
		||||
    lock_guard& operator=(lock_guard const&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	mutex_type& pm;
 | 
			
		||||
    mutex_type& pm;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Mutex>
 | 
			
		||||
class unique_lock
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	typedef Mutex mutex_type;
 | 
			
		||||
    typedef Mutex mutex_type;
 | 
			
		||||
 | 
			
		||||
	unique_lock()
 | 
			
		||||
		: pm(NULL), owns(false)
 | 
			
		||||
	{}
 | 
			
		||||
    unique_lock()
 | 
			
		||||
        : pm(NULL), owns(false)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
	/*explicit*/ unique_lock(mutex_type& m)
 | 
			
		||||
		: pm(&m), owns(true)
 | 
			
		||||
	{
 | 
			
		||||
		m.lock();
 | 
			
		||||
	}
 | 
			
		||||
    /*explicit*/ unique_lock(mutex_type& m)
 | 
			
		||||
        : pm(&m), owns(true)
 | 
			
		||||
    {
 | 
			
		||||
        m.lock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	unique_lock(mutex_type& m, defer_lock_t)
 | 
			
		||||
		: pm(&m), owns(false)
 | 
			
		||||
	{}
 | 
			
		||||
    unique_lock(mutex_type& m, defer_lock_t)
 | 
			
		||||
        : pm(&m), owns(false)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
	unique_lock(mutex_type& m, try_to_lock_t)
 | 
			
		||||
		: pm(&m), owns(m.try_lock())
 | 
			
		||||
	{}
 | 
			
		||||
    unique_lock(mutex_type& m, try_to_lock_t)
 | 
			
		||||
        : pm(&m), owns(m.try_lock())
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
	unique_lock(mutex_type& m, adopt_lock_t)
 | 
			
		||||
		: pm(&m), owns(true)
 | 
			
		||||
	{}
 | 
			
		||||
    unique_lock(mutex_type& m, adopt_lock_t)
 | 
			
		||||
        : pm(&m), owns(true)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
	//template <class Clock, class Duration>
 | 
			
		||||
	//unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
 | 
			
		||||
    //template <class Clock, class Duration>
 | 
			
		||||
    //unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
 | 
			
		||||
 | 
			
		||||
	//template <class Rep, class Period>
 | 
			
		||||
	//unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
 | 
			
		||||
    //template <class Rep, class Period>
 | 
			
		||||
    //unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
 | 
			
		||||
 | 
			
		||||
	~unique_lock()
 | 
			
		||||
	{
 | 
			
		||||
		if (owns_lock())
 | 
			
		||||
			mutex()->unlock();
 | 
			
		||||
	}
 | 
			
		||||
    ~unique_lock()
 | 
			
		||||
    {
 | 
			
		||||
        if (owns_lock())
 | 
			
		||||
            mutex()->unlock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef USE_RVALUE_REFERENCES
 | 
			
		||||
	unique_lock& operator=(const unique_lock&) /*= delete*/;
 | 
			
		||||
    unique_lock& operator=(const unique_lock&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
	unique_lock& operator=(unique_lock&& other)
 | 
			
		||||
	{
 | 
			
		||||
    unique_lock& operator=(unique_lock&& other)
 | 
			
		||||
    {
 | 
			
		||||
#else
 | 
			
		||||
	unique_lock& operator=(const unique_lock& u)
 | 
			
		||||
	{
 | 
			
		||||
		// ugly const_cast to get around lack of rvalue references
 | 
			
		||||
		unique_lock& other = const_cast<unique_lock&>(u);
 | 
			
		||||
    unique_lock& operator=(const unique_lock& u)
 | 
			
		||||
    {
 | 
			
		||||
        // ugly const_cast to get around lack of rvalue references
 | 
			
		||||
        unique_lock& other = const_cast<unique_lock&>(u);
 | 
			
		||||
#endif
 | 
			
		||||
		swap(other);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
        swap(other);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
#ifdef USE_RVALUE_REFERENCES
 | 
			
		||||
	unique_lock(const unique_lock&) /*= delete*/;
 | 
			
		||||
	
 | 
			
		||||
	unique_lock(unique_lock&& other)
 | 
			
		||||
		: pm(NULL), owns(false)
 | 
			
		||||
	{
 | 
			
		||||
    unique_lock(const unique_lock&) /*= delete*/;
 | 
			
		||||
    
 | 
			
		||||
    unique_lock(unique_lock&& other)
 | 
			
		||||
        : pm(NULL), owns(false)
 | 
			
		||||
    {
 | 
			
		||||
#else
 | 
			
		||||
	unique_lock(const unique_lock& u)
 | 
			
		||||
		: pm(NULL), owns(false)
 | 
			
		||||
	{
 | 
			
		||||
		// ugly const_cast to get around lack of rvalue references
 | 
			
		||||
		unique_lock& other = const_cast<unique_lock&>(u);	
 | 
			
		||||
    unique_lock(const unique_lock& u)
 | 
			
		||||
        : pm(NULL), owns(false)
 | 
			
		||||
    {
 | 
			
		||||
        // ugly const_cast to get around lack of rvalue references
 | 
			
		||||
        unique_lock& other = const_cast<unique_lock&>(u);    
 | 
			
		||||
#endif
 | 
			
		||||
		swap(other);
 | 
			
		||||
	}
 | 
			
		||||
        swap(other);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void lock()
 | 
			
		||||
	{
 | 
			
		||||
		mutex()->lock();
 | 
			
		||||
		owns = true;
 | 
			
		||||
	}
 | 
			
		||||
    void lock()
 | 
			
		||||
    {
 | 
			
		||||
        mutex()->lock();
 | 
			
		||||
        owns = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	bool try_lock()
 | 
			
		||||
	{
 | 
			
		||||
		owns = mutex()->try_lock();
 | 
			
		||||
		return owns;
 | 
			
		||||
	}
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
        owns = mutex()->try_lock();
 | 
			
		||||
        return owns;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	//template <class Rep, class Period>
 | 
			
		||||
	//bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
 | 
			
		||||
	//template <class Clock, class Duration>
 | 
			
		||||
	//bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
 | 
			
		||||
	
 | 
			
		||||
	void unlock()
 | 
			
		||||
	{
 | 
			
		||||
		mutex()->unlock();
 | 
			
		||||
		owns = false;
 | 
			
		||||
	}
 | 
			
		||||
    //template <class Rep, class Period>
 | 
			
		||||
    //bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
 | 
			
		||||
    //template <class Clock, class Duration>
 | 
			
		||||
    //bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
 | 
			
		||||
    
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
        mutex()->unlock();
 | 
			
		||||
        owns = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void swap(unique_lock& u)
 | 
			
		||||
	{
 | 
			
		||||
		std::swap(pm, u.pm);
 | 
			
		||||
		std::swap(owns, u.owns);
 | 
			
		||||
	}
 | 
			
		||||
    void swap(unique_lock& u)
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(pm, u.pm);
 | 
			
		||||
        std::swap(owns, u.owns);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	mutex_type* release()
 | 
			
		||||
	{
 | 
			
		||||
		auto const ret = mutex();
 | 
			
		||||
    mutex_type* release()
 | 
			
		||||
    {
 | 
			
		||||
        auto const ret = mutex();
 | 
			
		||||
 | 
			
		||||
		pm = NULL;
 | 
			
		||||
		owns = false;
 | 
			
		||||
        pm = NULL;
 | 
			
		||||
        owns = false;
 | 
			
		||||
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	bool owns_lock() const
 | 
			
		||||
	{
 | 
			
		||||
		return owns;
 | 
			
		||||
	}
 | 
			
		||||
    bool owns_lock() const
 | 
			
		||||
    {
 | 
			
		||||
        return owns;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	//explicit operator bool () const
 | 
			
		||||
	//{
 | 
			
		||||
	//	return owns_lock();
 | 
			
		||||
	//}
 | 
			
		||||
    //explicit operator bool () const
 | 
			
		||||
    //{
 | 
			
		||||
    //    return owns_lock();
 | 
			
		||||
    //}
 | 
			
		||||
 | 
			
		||||
	mutex_type* mutex() const
 | 
			
		||||
	{
 | 
			
		||||
		return pm;
 | 
			
		||||
	}
 | 
			
		||||
    mutex_type* mutex() const
 | 
			
		||||
    {
 | 
			
		||||
        return pm;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	mutex_type* pm;
 | 
			
		||||
	bool owns;
 | 
			
		||||
    mutex_type* pm;
 | 
			
		||||
    bool owns;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Mutex>
 | 
			
		||||
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y)
 | 
			
		||||
{
 | 
			
		||||
	x.swap(y);
 | 
			
		||||
    x.swap(y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
#ifndef STD_THREAD_H_
 | 
			
		||||
#define STD_THREAD_H_
 | 
			
		||||
 | 
			
		||||
#define GCC_VER(x,y,z)	((x) * 10000 + (y) * 100 + (z))
 | 
			
		||||
#define GCC_VER(x,y,z)    ((x) * 10000 + (y) * 100 + (z))
 | 
			
		||||
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
 | 
			
		||||
 | 
			
		||||
#ifndef __has_include
 | 
			
		||||
@@ -77,209 +77,209 @@ namespace std
 | 
			
		||||
class thread
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	typedef THREAD_HANDLE native_handle_type;
 | 
			
		||||
    typedef THREAD_HANDLE native_handle_type;
 | 
			
		||||
 | 
			
		||||
	class id
 | 
			
		||||
	{
 | 
			
		||||
		friend class thread;
 | 
			
		||||
	public:
 | 
			
		||||
		id() : m_thread(0) {}
 | 
			
		||||
		id(THREAD_ID _id) : m_thread(_id) {}
 | 
			
		||||
    class id
 | 
			
		||||
    {
 | 
			
		||||
        friend class thread;
 | 
			
		||||
    public:
 | 
			
		||||
        id() : m_thread(0) {}
 | 
			
		||||
        id(THREAD_ID _id) : m_thread(_id) {}
 | 
			
		||||
 | 
			
		||||
		bool operator==(const id& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return m_thread == rhs.m_thread;
 | 
			
		||||
		}
 | 
			
		||||
        bool operator==(const id& rhs) const
 | 
			
		||||
        {
 | 
			
		||||
            return m_thread == rhs.m_thread;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		bool operator!=(const id& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return !(*this == rhs);
 | 
			
		||||
		}
 | 
			
		||||
        bool operator!=(const id& rhs) const
 | 
			
		||||
        {
 | 
			
		||||
            return !(*this == rhs);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		bool operator<(const id& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return m_thread < rhs.m_thread;
 | 
			
		||||
		}
 | 
			
		||||
        bool operator<(const id& rhs) const
 | 
			
		||||
        {
 | 
			
		||||
            return m_thread < rhs.m_thread;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		THREAD_ID m_thread;
 | 
			
		||||
	};
 | 
			
		||||
    private:
 | 
			
		||||
        THREAD_ID m_thread;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
	// no variadic template support in msvc
 | 
			
		||||
	//template <typename C, typename... A>
 | 
			
		||||
	//thread(C&& func, A&&... args);
 | 
			
		||||
    // no variadic template support in msvc
 | 
			
		||||
    //template <typename C, typename... A>
 | 
			
		||||
    //thread(C&& func, A&&... args);
 | 
			
		||||
 | 
			
		||||
	template <typename C>
 | 
			
		||||
	thread(C func)
 | 
			
		||||
	{
 | 
			
		||||
		StartThread(new Func<C>(func));
 | 
			
		||||
	}
 | 
			
		||||
    template <typename C>
 | 
			
		||||
    thread(C func)
 | 
			
		||||
    {
 | 
			
		||||
        StartThread(new Func<C>(func));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	template <typename C, typename A>
 | 
			
		||||
	thread(C func, A arg)
 | 
			
		||||
	{
 | 
			
		||||
		StartThread(new FuncArg<C, A>(func, arg));
 | 
			
		||||
	}
 | 
			
		||||
    template <typename C, typename A>
 | 
			
		||||
    thread(C func, A arg)
 | 
			
		||||
    {
 | 
			
		||||
        StartThread(new FuncArg<C, A>(func, arg));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	thread() /*= default;*/ {}
 | 
			
		||||
    thread() /*= default;*/ {}
 | 
			
		||||
 | 
			
		||||
#ifdef USE_RVALUE_REFERENCES
 | 
			
		||||
	thread(const thread&) /*= delete*/;
 | 
			
		||||
    thread(const thread&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
	thread(thread&& other)
 | 
			
		||||
	{
 | 
			
		||||
    thread(thread&& other)
 | 
			
		||||
    {
 | 
			
		||||
#else
 | 
			
		||||
	thread(const thread& t)
 | 
			
		||||
	{
 | 
			
		||||
		// ugly const_cast to get around lack of rvalue references
 | 
			
		||||
		thread& other = const_cast<thread&>(t);
 | 
			
		||||
    thread(const thread& t)
 | 
			
		||||
    {
 | 
			
		||||
        // ugly const_cast to get around lack of rvalue references
 | 
			
		||||
        thread& other = const_cast<thread&>(t);
 | 
			
		||||
#endif
 | 
			
		||||
		swap(other);
 | 
			
		||||
	}
 | 
			
		||||
        swap(other);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef USE_RVALUE_REFERENCES
 | 
			
		||||
	thread& operator=(const thread&) /*= delete*/;
 | 
			
		||||
    thread& operator=(const thread&) /*= delete*/;
 | 
			
		||||
 | 
			
		||||
	thread& operator=(thread&& other)
 | 
			
		||||
	{
 | 
			
		||||
    thread& operator=(thread&& other)
 | 
			
		||||
    {
 | 
			
		||||
#else
 | 
			
		||||
	thread& operator=(const thread& t)
 | 
			
		||||
	{
 | 
			
		||||
		// ugly const_cast to get around lack of rvalue references
 | 
			
		||||
		thread& other = const_cast<thread&>(t);
 | 
			
		||||
    thread& operator=(const thread& t)
 | 
			
		||||
    {
 | 
			
		||||
        // ugly const_cast to get around lack of rvalue references
 | 
			
		||||
        thread& other = const_cast<thread&>(t);
 | 
			
		||||
#endif
 | 
			
		||||
		if (joinable())
 | 
			
		||||
			detach();
 | 
			
		||||
		swap(other);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
        if (joinable())
 | 
			
		||||
            detach();
 | 
			
		||||
        swap(other);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	~thread()
 | 
			
		||||
	{
 | 
			
		||||
		if (joinable())
 | 
			
		||||
			detach();
 | 
			
		||||
	}
 | 
			
		||||
    ~thread()
 | 
			
		||||
    {
 | 
			
		||||
        if (joinable())
 | 
			
		||||
            detach();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	bool joinable() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_id != id();
 | 
			
		||||
	}
 | 
			
		||||
    bool joinable() const
 | 
			
		||||
    {
 | 
			
		||||
        return m_id != id();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	id get_id() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_id;
 | 
			
		||||
	}
 | 
			
		||||
    id get_id() const
 | 
			
		||||
    {
 | 
			
		||||
        return m_id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	native_handle_type native_handle()
 | 
			
		||||
	{
 | 
			
		||||
    native_handle_type native_handle()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		return m_handle;
 | 
			
		||||
        return m_handle;
 | 
			
		||||
#else
 | 
			
		||||
		return m_id.m_thread;
 | 
			
		||||
        return m_id.m_thread;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void join()
 | 
			
		||||
	{
 | 
			
		||||
    void join()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		WaitForSingleObject(m_handle, INFINITE);
 | 
			
		||||
		detach();
 | 
			
		||||
        WaitForSingleObject(m_handle, INFINITE);
 | 
			
		||||
        detach();
 | 
			
		||||
#else
 | 
			
		||||
		pthread_join(m_id.m_thread, NULL);
 | 
			
		||||
		m_id = id();
 | 
			
		||||
        pthread_join(m_id.m_thread, NULL);
 | 
			
		||||
        m_id = id();
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void detach()
 | 
			
		||||
	{
 | 
			
		||||
    void detach()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		CloseHandle(m_handle);
 | 
			
		||||
        CloseHandle(m_handle);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_detach(m_id.m_thread);
 | 
			
		||||
        pthread_detach(m_id.m_thread);
 | 
			
		||||
#endif
 | 
			
		||||
		m_id = id();
 | 
			
		||||
	}
 | 
			
		||||
        m_id = id();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void swap(thread& other)
 | 
			
		||||
	{
 | 
			
		||||
		std::swap(m_id, other.m_id);
 | 
			
		||||
    void swap(thread& other)
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(m_id, other.m_id);
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		std::swap(m_handle, other.m_handle);
 | 
			
		||||
        std::swap(m_handle, other.m_handle);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	static unsigned hardware_concurrency()
 | 
			
		||||
	{
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static unsigned hardware_concurrency()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		SYSTEM_INFO sysinfo;
 | 
			
		||||
		GetSystemInfo(&sysinfo);
 | 
			
		||||
		return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);
 | 
			
		||||
        SYSTEM_INFO sysinfo;
 | 
			
		||||
        GetSystemInfo(&sysinfo);
 | 
			
		||||
        return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);
 | 
			
		||||
#else
 | 
			
		||||
		return 0;
 | 
			
		||||
        return 0;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	id m_id;
 | 
			
		||||
	
 | 
			
		||||
    id m_id;
 | 
			
		||||
    
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	native_handle_type m_handle;
 | 
			
		||||
    native_handle_type m_handle;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	template <typename F>
 | 
			
		||||
	void StartThread(F* param)
 | 
			
		||||
	{
 | 
			
		||||
    template <typename F>
 | 
			
		||||
    void StartThread(F* param)
 | 
			
		||||
    {
 | 
			
		||||
#ifdef USE_BEGINTHREADEX
 | 
			
		||||
		m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
 | 
			
		||||
        m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
		m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
 | 
			
		||||
        m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
 | 
			
		||||
#else
 | 
			
		||||
		pthread_attr_t attr;
 | 
			
		||||
		pthread_attr_init(&attr);
 | 
			
		||||
		pthread_attr_setstacksize(&attr, 1024 * 1024);
 | 
			
		||||
		if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param))
 | 
			
		||||
			m_id = id();
 | 
			
		||||
        pthread_attr_t attr;
 | 
			
		||||
        pthread_attr_init(&attr);
 | 
			
		||||
        pthread_attr_setstacksize(&attr, 1024 * 1024);
 | 
			
		||||
        if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param))
 | 
			
		||||
            m_id = id();
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	template <typename C>
 | 
			
		||||
	class Func
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		Func(C _func) : func(_func) {}
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <typename C>
 | 
			
		||||
    class Func
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        Func(C _func) : func(_func) {}
 | 
			
		||||
 | 
			
		||||
		void Run() { func(); }
 | 
			
		||||
        void Run() { func(); }
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		C const func;
 | 
			
		||||
	};
 | 
			
		||||
    private:
 | 
			
		||||
        C const func;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
	template <typename C, typename A>
 | 
			
		||||
	class FuncArg
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		FuncArg(C _func, A _arg) : func(_func), arg(_arg) {}
 | 
			
		||||
    template <typename C, typename A>
 | 
			
		||||
    class FuncArg
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        FuncArg(C _func, A _arg) : func(_func), arg(_arg) {}
 | 
			
		||||
 | 
			
		||||
		void Run() { func(arg); }
 | 
			
		||||
        void Run() { func(arg); }
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		C const func;
 | 
			
		||||
		A arg;
 | 
			
		||||
	};
 | 
			
		||||
    private:
 | 
			
		||||
        C const func;
 | 
			
		||||
        A arg;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
	template <typename F>
 | 
			
		||||
	static THREAD_RETURN RunAndDelete(void* param)
 | 
			
		||||
	{
 | 
			
		||||
    template <typename F>
 | 
			
		||||
    static THREAD_RETURN RunAndDelete(void* param)
 | 
			
		||||
    {
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 | 
			
		||||
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 | 
			
		||||
#endif
 | 
			
		||||
		static_cast<F*>(param)->Run();
 | 
			
		||||
		delete static_cast<F*>(param);
 | 
			
		||||
        static_cast<F*>(param)->Run();
 | 
			
		||||
        delete static_cast<F*>(param);
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
		[pool release];
 | 
			
		||||
        [pool release];
 | 
			
		||||
#endif
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
namespace this_thread
 | 
			
		||||
@@ -288,24 +288,24 @@ namespace this_thread
 | 
			
		||||
inline void yield()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	SwitchToThread();
 | 
			
		||||
    SwitchToThread();
 | 
			
		||||
#else
 | 
			
		||||
	sleep(0);
 | 
			
		||||
    sleep(0);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline thread::id get_id()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	return GetCurrentThreadId();
 | 
			
		||||
    return GetCurrentThreadId();
 | 
			
		||||
#else
 | 
			
		||||
	return pthread_self();
 | 
			
		||||
    return pthread_self();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}	// namespace this_thread
 | 
			
		||||
}    // namespace this_thread
 | 
			
		||||
 | 
			
		||||
}	// namespace std
 | 
			
		||||
}    // namespace std
 | 
			
		||||
 | 
			
		||||
#undef USE_RVALUE_REFERENCES
 | 
			
		||||
#undef USE_BEGINTHREADEX
 | 
			
		||||
 
 | 
			
		||||
@@ -11,131 +11,131 @@
 | 
			
		||||
#include "string_util.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	#include <Windows.h>
 | 
			
		||||
    #include <Windows.h>
 | 
			
		||||
#else
 | 
			
		||||
	#include <iconv.h>
 | 
			
		||||
	#include <errno.h>
 | 
			
		||||
    #include <iconv.h>
 | 
			
		||||
    #include <errno.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// faster than sscanf
 | 
			
		||||
bool AsciiToHex(const char* _szValue, u32& result)
 | 
			
		||||
{
 | 
			
		||||
	char *endptr = NULL;
 | 
			
		||||
	const u32 value = strtoul(_szValue, &endptr, 16);
 | 
			
		||||
    char *endptr = NULL;
 | 
			
		||||
    const u32 value = strtoul(_szValue, &endptr, 16);
 | 
			
		||||
 | 
			
		||||
	if (!endptr || *endptr)
 | 
			
		||||
		return false;
 | 
			
		||||
    if (!endptr || *endptr)
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
	result = value;
 | 
			
		||||
	return true;
 | 
			
		||||
    result = value;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args)
 | 
			
		||||
{
 | 
			
		||||
	int writtenCount;
 | 
			
		||||
    int writtenCount;
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	// You would think *printf are simple, right? Iterate on each character,
 | 
			
		||||
	// if it's a format specifier handle it properly, etc.
 | 
			
		||||
	//
 | 
			
		||||
	// Nooooo. Not according to the C standard.
 | 
			
		||||
	//
 | 
			
		||||
	// According to the C99 standard (7.19.6.1 "The fprintf function")
 | 
			
		||||
	//     The format shall be a multibyte character sequence
 | 
			
		||||
	//
 | 
			
		||||
	// Because some character encodings might have '%' signs in the middle of
 | 
			
		||||
	// a multibyte sequence (SJIS for example only specifies that the first
 | 
			
		||||
	// byte of a 2 byte sequence is "high", the second byte can be anything),
 | 
			
		||||
	// printf functions have to decode the multibyte sequences and try their
 | 
			
		||||
	// best to not screw up.
 | 
			
		||||
	//
 | 
			
		||||
	// Unfortunately, on Windows, the locale for most languages is not UTF-8
 | 
			
		||||
	// as we would need. Notably, for zh_TW, Windows chooses EUC-CN as the
 | 
			
		||||
	// locale, and completely fails when trying to decode UTF-8 as EUC-CN.
 | 
			
		||||
	//
 | 
			
		||||
	// On the other hand, the fix is simple: because we use UTF-8, no such
 | 
			
		||||
	// multibyte handling is required as we can simply assume that no '%' char
 | 
			
		||||
	// will be present in the middle of a multibyte sequence.
 | 
			
		||||
	//
 | 
			
		||||
	// This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l.
 | 
			
		||||
	static locale_t c_locale = NULL;
 | 
			
		||||
	if (!c_locale)
 | 
			
		||||
		c_locale = _create_locale(LC_ALL, ".1252");
 | 
			
		||||
	writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args);
 | 
			
		||||
    // You would think *printf are simple, right? Iterate on each character,
 | 
			
		||||
    // if it's a format specifier handle it properly, etc.
 | 
			
		||||
    //
 | 
			
		||||
    // Nooooo. Not according to the C standard.
 | 
			
		||||
    //
 | 
			
		||||
    // According to the C99 standard (7.19.6.1 "The fprintf function")
 | 
			
		||||
    //     The format shall be a multibyte character sequence
 | 
			
		||||
    //
 | 
			
		||||
    // Because some character encodings might have '%' signs in the middle of
 | 
			
		||||
    // a multibyte sequence (SJIS for example only specifies that the first
 | 
			
		||||
    // byte of a 2 byte sequence is "high", the second byte can be anything),
 | 
			
		||||
    // printf functions have to decode the multibyte sequences and try their
 | 
			
		||||
    // best to not screw up.
 | 
			
		||||
    //
 | 
			
		||||
    // Unfortunately, on Windows, the locale for most languages is not UTF-8
 | 
			
		||||
    // as we would need. Notably, for zh_TW, Windows chooses EUC-CN as the
 | 
			
		||||
    // locale, and completely fails when trying to decode UTF-8 as EUC-CN.
 | 
			
		||||
    //
 | 
			
		||||
    // On the other hand, the fix is simple: because we use UTF-8, no such
 | 
			
		||||
    // multibyte handling is required as we can simply assume that no '%' char
 | 
			
		||||
    // will be present in the middle of a multibyte sequence.
 | 
			
		||||
    //
 | 
			
		||||
    // This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l.
 | 
			
		||||
    static locale_t c_locale = NULL;
 | 
			
		||||
    if (!c_locale)
 | 
			
		||||
        c_locale = _create_locale(LC_ALL, ".1252");
 | 
			
		||||
    writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args);
 | 
			
		||||
#else
 | 
			
		||||
	writtenCount = vsnprintf(out, outsize, format, args);
 | 
			
		||||
    writtenCount = vsnprintf(out, outsize, format, args);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (writtenCount > 0 && writtenCount < outsize)
 | 
			
		||||
	{
 | 
			
		||||
		out[writtenCount] = '\0';
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		out[outsize - 1] = '\0';
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
    if (writtenCount > 0 && writtenCount < outsize)
 | 
			
		||||
    {
 | 
			
		||||
        out[writtenCount] = '\0';
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        out[outsize - 1] = '\0';
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string StringFromFormat(const char* format, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list args;
 | 
			
		||||
	char *buf = NULL;
 | 
			
		||||
    va_list args;
 | 
			
		||||
    char *buf = NULL;
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	int required = 0;
 | 
			
		||||
    int required = 0;
 | 
			
		||||
 | 
			
		||||
	va_start(args, format);
 | 
			
		||||
	required = _vscprintf(format, args);
 | 
			
		||||
	buf = new char[required + 1];
 | 
			
		||||
	CharArrayFromFormatV(buf, required + 1, format, args);
 | 
			
		||||
	va_end(args);
 | 
			
		||||
    va_start(args, format);
 | 
			
		||||
    required = _vscprintf(format, args);
 | 
			
		||||
    buf = new char[required + 1];
 | 
			
		||||
    CharArrayFromFormatV(buf, required + 1, format, args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
 | 
			
		||||
	std::string temp = buf;
 | 
			
		||||
	delete[] buf;
 | 
			
		||||
    std::string temp = buf;
 | 
			
		||||
    delete[] buf;
 | 
			
		||||
#else
 | 
			
		||||
	va_start(args, format);
 | 
			
		||||
	if (vasprintf(&buf, format, args) < 0)
 | 
			
		||||
		ERROR_LOG(COMMON, "Unable to allocate memory for string");
 | 
			
		||||
	va_end(args);
 | 
			
		||||
    va_start(args, format);
 | 
			
		||||
    if (vasprintf(&buf, format, args) < 0)
 | 
			
		||||
        ERROR_LOG(COMMON, "Unable to allocate memory for string");
 | 
			
		||||
    va_end(args);
 | 
			
		||||
 | 
			
		||||
	std::string temp = buf;
 | 
			
		||||
	free(buf);
 | 
			
		||||
    std::string temp = buf;
 | 
			
		||||
    free(buf);
 | 
			
		||||
#endif
 | 
			
		||||
	return temp;
 | 
			
		||||
    return temp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// For Debugging. Read out an u8 array.
 | 
			
		||||
std::string ArrayToString(const u8 *data, u32 size, int line_len, bool spaces)
 | 
			
		||||
{
 | 
			
		||||
	std::ostringstream oss;
 | 
			
		||||
	oss << std::setfill('0') << std::hex;
 | 
			
		||||
	
 | 
			
		||||
	for (int line = 0; size; ++data, --size)
 | 
			
		||||
	{
 | 
			
		||||
		oss << std::setw(2) << (int)*data;
 | 
			
		||||
		
 | 
			
		||||
		if (line_len == ++line)
 | 
			
		||||
		{
 | 
			
		||||
			oss << '\n';
 | 
			
		||||
			line = 0;
 | 
			
		||||
		}
 | 
			
		||||
		else if (spaces)
 | 
			
		||||
			oss << ' ';
 | 
			
		||||
	}
 | 
			
		||||
    std::ostringstream oss;
 | 
			
		||||
    oss << std::setfill('0') << std::hex;
 | 
			
		||||
    
 | 
			
		||||
    for (int line = 0; size; ++data, --size)
 | 
			
		||||
    {
 | 
			
		||||
        oss << std::setw(2) << (int)*data;
 | 
			
		||||
        
 | 
			
		||||
        if (line_len == ++line)
 | 
			
		||||
        {
 | 
			
		||||
            oss << '\n';
 | 
			
		||||
            line = 0;
 | 
			
		||||
        }
 | 
			
		||||
        else if (spaces)
 | 
			
		||||
            oss << ' ';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	return oss.str();
 | 
			
		||||
    return oss.str();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Turns "  hej " into "hej". Also handles tabs.
 | 
			
		||||
std::string StripSpaces(const std::string &str)
 | 
			
		||||
{
 | 
			
		||||
	const size_t s = str.find_first_not_of(" \t\r\n");
 | 
			
		||||
    const size_t s = str.find_first_not_of(" \t\r\n");
 | 
			
		||||
 | 
			
		||||
	if (str.npos != s)
 | 
			
		||||
		return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1);
 | 
			
		||||
	else
 | 
			
		||||
		return "";
 | 
			
		||||
    if (str.npos != s)
 | 
			
		||||
        return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1);
 | 
			
		||||
    else
 | 
			
		||||
        return "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// "\"hello\"" is turned to "hello"
 | 
			
		||||
@@ -143,137 +143,137 @@ std::string StripSpaces(const std::string &str)
 | 
			
		||||
// ends, as done by StripSpaces above, for example.
 | 
			
		||||
std::string StripQuotes(const std::string& s)
 | 
			
		||||
{
 | 
			
		||||
	if (s.size() && '\"' == s[0] && '\"' == *s.rbegin())
 | 
			
		||||
		return s.substr(1, s.size() - 2);
 | 
			
		||||
	else
 | 
			
		||||
		return s;
 | 
			
		||||
    if (s.size() && '\"' == s[0] && '\"' == *s.rbegin())
 | 
			
		||||
        return s.substr(1, s.size() - 2);
 | 
			
		||||
    else
 | 
			
		||||
        return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool TryParse(const std::string &str, u32 *const output)
 | 
			
		||||
{
 | 
			
		||||
	char *endptr = NULL;
 | 
			
		||||
    char *endptr = NULL;
 | 
			
		||||
 | 
			
		||||
	// Reset errno to a value other than ERANGE
 | 
			
		||||
	errno = 0;
 | 
			
		||||
    // Reset errno to a value other than ERANGE
 | 
			
		||||
    errno = 0;
 | 
			
		||||
 | 
			
		||||
	unsigned long value = strtoul(str.c_str(), &endptr, 0);
 | 
			
		||||
	
 | 
			
		||||
	if (!endptr || *endptr)
 | 
			
		||||
		return false;
 | 
			
		||||
    unsigned long value = strtoul(str.c_str(), &endptr, 0);
 | 
			
		||||
    
 | 
			
		||||
    if (!endptr || *endptr)
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
	if (errno == ERANGE)
 | 
			
		||||
		return false;
 | 
			
		||||
    if (errno == ERANGE)
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
#if ULONG_MAX > UINT_MAX
 | 
			
		||||
	if (value >= 0x100000000ull
 | 
			
		||||
	    && value <= 0xFFFFFFFF00000000ull)
 | 
			
		||||
		return false;
 | 
			
		||||
    if (value >= 0x100000000ull
 | 
			
		||||
        && value <= 0xFFFFFFFF00000000ull)
 | 
			
		||||
        return false;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	*output = static_cast<u32>(value);
 | 
			
		||||
	return true;
 | 
			
		||||
    *output = static_cast<u32>(value);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool TryParse(const std::string &str, bool *const output)
 | 
			
		||||
{
 | 
			
		||||
	if ("1" == str || !strcasecmp("true", str.c_str()))
 | 
			
		||||
		*output = true;
 | 
			
		||||
	else if ("0" == str || !strcasecmp("false", str.c_str()))
 | 
			
		||||
		*output = false;
 | 
			
		||||
	else
 | 
			
		||||
		return false;
 | 
			
		||||
    if ("1" == str || !strcasecmp("true", str.c_str()))
 | 
			
		||||
        *output = true;
 | 
			
		||||
    else if ("0" == str || !strcasecmp("false", str.c_str()))
 | 
			
		||||
        *output = false;
 | 
			
		||||
    else
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string StringFromInt(int value)
 | 
			
		||||
{
 | 
			
		||||
	char temp[16];
 | 
			
		||||
	sprintf(temp, "%i", value);
 | 
			
		||||
	return temp;
 | 
			
		||||
    char temp[16];
 | 
			
		||||
    sprintf(temp, "%i", value);
 | 
			
		||||
    return temp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string StringFromBool(bool value)
 | 
			
		||||
{
 | 
			
		||||
	return value ? "True" : "False";
 | 
			
		||||
    return value ? "True" : "False";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension)
 | 
			
		||||
{
 | 
			
		||||
	if (full_path.empty())
 | 
			
		||||
		return false;
 | 
			
		||||
    if (full_path.empty())
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
	size_t dir_end = full_path.find_last_of("/"
 | 
			
		||||
	// windows needs the : included for something like just "C:" to be considered a directory
 | 
			
		||||
    size_t dir_end = full_path.find_last_of("/"
 | 
			
		||||
    // windows needs the : included for something like just "C:" to be considered a directory
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		":"
 | 
			
		||||
        ":"
 | 
			
		||||
#endif
 | 
			
		||||
	);
 | 
			
		||||
	if (std::string::npos == dir_end)
 | 
			
		||||
		dir_end = 0;
 | 
			
		||||
	else
 | 
			
		||||
		dir_end += 1;
 | 
			
		||||
    );
 | 
			
		||||
    if (std::string::npos == dir_end)
 | 
			
		||||
        dir_end = 0;
 | 
			
		||||
    else
 | 
			
		||||
        dir_end += 1;
 | 
			
		||||
 | 
			
		||||
	size_t fname_end = full_path.rfind('.');
 | 
			
		||||
	if (fname_end < dir_end || std::string::npos == fname_end)
 | 
			
		||||
		fname_end = full_path.size();
 | 
			
		||||
    size_t fname_end = full_path.rfind('.');
 | 
			
		||||
    if (fname_end < dir_end || std::string::npos == fname_end)
 | 
			
		||||
        fname_end = full_path.size();
 | 
			
		||||
 | 
			
		||||
	if (_pPath)
 | 
			
		||||
		*_pPath = full_path.substr(0, dir_end);
 | 
			
		||||
    if (_pPath)
 | 
			
		||||
        *_pPath = full_path.substr(0, dir_end);
 | 
			
		||||
 | 
			
		||||
	if (_pFilename)
 | 
			
		||||
		*_pFilename = full_path.substr(dir_end, fname_end - dir_end);
 | 
			
		||||
    if (_pFilename)
 | 
			
		||||
        *_pFilename = full_path.substr(dir_end, fname_end - dir_end);
 | 
			
		||||
 | 
			
		||||
	if (_pExtension)
 | 
			
		||||
		*_pExtension = full_path.substr(fname_end);
 | 
			
		||||
    if (_pExtension)
 | 
			
		||||
        *_pExtension = full_path.substr(fname_end);
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, const std::string& _Filename)
 | 
			
		||||
{
 | 
			
		||||
	_CompleteFilename = _Path;
 | 
			
		||||
    _CompleteFilename = _Path;
 | 
			
		||||
 | 
			
		||||
	// check for seperator
 | 
			
		||||
	if (DIR_SEP_CHR != *_CompleteFilename.rbegin())
 | 
			
		||||
		_CompleteFilename += DIR_SEP_CHR;
 | 
			
		||||
    // check for seperator
 | 
			
		||||
    if (DIR_SEP_CHR != *_CompleteFilename.rbegin())
 | 
			
		||||
        _CompleteFilename += DIR_SEP_CHR;
 | 
			
		||||
 | 
			
		||||
	// add the filename
 | 
			
		||||
	_CompleteFilename += _Filename;
 | 
			
		||||
    // add the filename
 | 
			
		||||
    _CompleteFilename += _Filename;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SplitString(const std::string& str, const char delim, std::vector<std::string>& output)
 | 
			
		||||
{
 | 
			
		||||
	std::istringstream iss(str);
 | 
			
		||||
	output.resize(1);
 | 
			
		||||
    std::istringstream iss(str);
 | 
			
		||||
    output.resize(1);
 | 
			
		||||
 | 
			
		||||
	while (std::getline(iss, *output.rbegin(), delim))
 | 
			
		||||
		output.push_back("");
 | 
			
		||||
    while (std::getline(iss, *output.rbegin(), delim))
 | 
			
		||||
        output.push_back("");
 | 
			
		||||
 | 
			
		||||
	output.pop_back();
 | 
			
		||||
    output.pop_back();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string TabsToSpaces(int tab_size, const std::string &in)
 | 
			
		||||
{
 | 
			
		||||
	const std::string spaces(tab_size, ' ');
 | 
			
		||||
	std::string out(in);
 | 
			
		||||
    const std::string spaces(tab_size, ' ');
 | 
			
		||||
    std::string out(in);
 | 
			
		||||
 | 
			
		||||
	size_t i = 0;
 | 
			
		||||
	while (out.npos != (i = out.find('\t')))
 | 
			
		||||
		out.replace(i, 1, spaces);
 | 
			
		||||
    size_t i = 0;
 | 
			
		||||
    while (out.npos != (i = out.find('\t')))
 | 
			
		||||
        out.replace(i, 1, spaces);
 | 
			
		||||
 | 
			
		||||
	return out;
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest)
 | 
			
		||||
{
 | 
			
		||||
	while(1)
 | 
			
		||||
	{
 | 
			
		||||
		size_t pos = result.find(src);
 | 
			
		||||
		if (pos == std::string::npos) break;
 | 
			
		||||
		result.replace(pos, src.size(), dest);
 | 
			
		||||
	}
 | 
			
		||||
	return result;
 | 
			
		||||
    while(1)
 | 
			
		||||
    {
 | 
			
		||||
        size_t pos = result.find(src);
 | 
			
		||||
        if (pos == std::string::npos) break;
 | 
			
		||||
        result.replace(pos, src.size(), dest);
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UriDecode and UriEncode are from http://www.codeguru.com/cpp/cpp/string/conversions/print.php/c12759
 | 
			
		||||
@@ -287,161 +287,161 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st
 | 
			
		||||
 | 
			
		||||
const char HEX2DEC[256] = 
 | 
			
		||||
{
 | 
			
		||||
	/*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */
 | 
			
		||||
	/* 0 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* 1 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* 2 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* 3 */  0, 1, 2, 3,  4, 5, 6, 7,  8, 9,16,16, 16,16,16,16,
 | 
			
		||||
    /*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */
 | 
			
		||||
    /* 0 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* 1 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* 2 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* 3 */  0, 1, 2, 3,  4, 5, 6, 7,  8, 9,16,16, 16,16,16,16,
 | 
			
		||||
 | 
			
		||||
	/* 4 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* 5 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* 6 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* 7 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* 4 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* 5 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* 6 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* 7 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
 | 
			
		||||
	/* 8 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* 9 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* A */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* B */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* 8 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* 9 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* A */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* B */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
 | 
			
		||||
	/* C */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* D */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* E */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
	/* F */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16
 | 
			
		||||
    /* C */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* D */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* E */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16,
 | 
			
		||||
    /* F */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::string UriDecode(const std::string & sSrc)
 | 
			
		||||
{
 | 
			
		||||
	// Note from RFC1630:  "Sequences which start with a percent sign
 | 
			
		||||
	// but are not followed by two hexadecimal characters (0-9, A-F) are reserved
 | 
			
		||||
	// for future extension"
 | 
			
		||||
    // Note from RFC1630:  "Sequences which start with a percent sign
 | 
			
		||||
    // but are not followed by two hexadecimal characters (0-9, A-F) are reserved
 | 
			
		||||
    // for future extension"
 | 
			
		||||
 | 
			
		||||
	const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
 | 
			
		||||
	const size_t SRC_LEN = sSrc.length();
 | 
			
		||||
	const unsigned char * const SRC_END = pSrc + SRC_LEN;
 | 
			
		||||
	const unsigned char * const SRC_LAST_DEC = SRC_END - 2;   // last decodable '%' 
 | 
			
		||||
    const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
 | 
			
		||||
    const size_t SRC_LEN = sSrc.length();
 | 
			
		||||
    const unsigned char * const SRC_END = pSrc + SRC_LEN;
 | 
			
		||||
    const unsigned char * const SRC_LAST_DEC = SRC_END - 2;   // last decodable '%' 
 | 
			
		||||
 | 
			
		||||
	char * const pStart = new char[SRC_LEN];
 | 
			
		||||
	char * pEnd = pStart;
 | 
			
		||||
    char * const pStart = new char[SRC_LEN];
 | 
			
		||||
    char * pEnd = pStart;
 | 
			
		||||
 | 
			
		||||
	while (pSrc < SRC_LAST_DEC)
 | 
			
		||||
	{
 | 
			
		||||
		if (*pSrc == '%')
 | 
			
		||||
		{
 | 
			
		||||
			char dec1, dec2;
 | 
			
		||||
			if (16 != (dec1 = HEX2DEC[*(pSrc + 1)])
 | 
			
		||||
				&& 16 != (dec2 = HEX2DEC[*(pSrc + 2)]))
 | 
			
		||||
			{
 | 
			
		||||
				*pEnd++ = (dec1 << 4) + dec2;
 | 
			
		||||
				pSrc += 3;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
    while (pSrc < SRC_LAST_DEC)
 | 
			
		||||
    {
 | 
			
		||||
        if (*pSrc == '%')
 | 
			
		||||
        {
 | 
			
		||||
            char dec1, dec2;
 | 
			
		||||
            if (16 != (dec1 = HEX2DEC[*(pSrc + 1)])
 | 
			
		||||
                && 16 != (dec2 = HEX2DEC[*(pSrc + 2)]))
 | 
			
		||||
            {
 | 
			
		||||
                *pEnd++ = (dec1 << 4) + dec2;
 | 
			
		||||
                pSrc += 3;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		*pEnd++ = *pSrc++;
 | 
			
		||||
	}
 | 
			
		||||
        *pEnd++ = *pSrc++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// the last 2- chars
 | 
			
		||||
	while (pSrc < SRC_END)
 | 
			
		||||
		*pEnd++ = *pSrc++;
 | 
			
		||||
    // the last 2- chars
 | 
			
		||||
    while (pSrc < SRC_END)
 | 
			
		||||
        *pEnd++ = *pSrc++;
 | 
			
		||||
 | 
			
		||||
	std::string sResult(pStart, pEnd);
 | 
			
		||||
	delete [] pStart;
 | 
			
		||||
	return sResult;
 | 
			
		||||
    std::string sResult(pStart, pEnd);
 | 
			
		||||
    delete [] pStart;
 | 
			
		||||
    return sResult;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Only alphanum is safe.
 | 
			
		||||
const char SAFE[256] =
 | 
			
		||||
{
 | 
			
		||||
	/*      0 1 2 3  4 5 6 7  8 9 A B  C D E F */
 | 
			
		||||
	/* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
	/* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
	/* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
	/* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0,
 | 
			
		||||
    /*      0 1 2 3  4 5 6 7  8 9 A B  C D E F */
 | 
			
		||||
    /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
    /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
    /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
    /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0,
 | 
			
		||||
 | 
			
		||||
	/* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
 | 
			
		||||
	/* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
 | 
			
		||||
	/* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
 | 
			
		||||
	/* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
 | 
			
		||||
    /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
 | 
			
		||||
    /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
 | 
			
		||||
    /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
 | 
			
		||||
    /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
 | 
			
		||||
 | 
			
		||||
	/* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
	/* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
	/* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
	/* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
    /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
    /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
    /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
    /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
 | 
			
		||||
	/* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
	/* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
	/* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
	/* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
 | 
			
		||||
    /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
    /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
    /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
 | 
			
		||||
    /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::string UriEncode(const std::string & sSrc)
 | 
			
		||||
{
 | 
			
		||||
	const char DEC2HEX[16 + 1] = "0123456789ABCDEF";
 | 
			
		||||
	const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
 | 
			
		||||
	const size_t SRC_LEN = sSrc.length();
 | 
			
		||||
	unsigned char * const pStart = new unsigned char[SRC_LEN * 3];
 | 
			
		||||
	unsigned char * pEnd = pStart;
 | 
			
		||||
	const unsigned char * const SRC_END = pSrc + SRC_LEN;
 | 
			
		||||
    const char DEC2HEX[16 + 1] = "0123456789ABCDEF";
 | 
			
		||||
    const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
 | 
			
		||||
    const size_t SRC_LEN = sSrc.length();
 | 
			
		||||
    unsigned char * const pStart = new unsigned char[SRC_LEN * 3];
 | 
			
		||||
    unsigned char * pEnd = pStart;
 | 
			
		||||
    const unsigned char * const SRC_END = pSrc + SRC_LEN;
 | 
			
		||||
 | 
			
		||||
	for (; pSrc < SRC_END; ++pSrc)
 | 
			
		||||
	{
 | 
			
		||||
		if (SAFE[*pSrc]) 
 | 
			
		||||
			*pEnd++ = *pSrc;
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			// escape this char
 | 
			
		||||
			*pEnd++ = '%';
 | 
			
		||||
			*pEnd++ = DEC2HEX[*pSrc >> 4];
 | 
			
		||||
			*pEnd++ = DEC2HEX[*pSrc & 0x0F];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    for (; pSrc < SRC_END; ++pSrc)
 | 
			
		||||
    {
 | 
			
		||||
        if (SAFE[*pSrc]) 
 | 
			
		||||
            *pEnd++ = *pSrc;
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // escape this char
 | 
			
		||||
            *pEnd++ = '%';
 | 
			
		||||
            *pEnd++ = DEC2HEX[*pSrc >> 4];
 | 
			
		||||
            *pEnd++ = DEC2HEX[*pSrc & 0x0F];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	std::string sResult((char *)pStart, (char *)pEnd);
 | 
			
		||||
	delete [] pStart;
 | 
			
		||||
	return sResult;
 | 
			
		||||
    std::string sResult((char *)pStart, (char *)pEnd);
 | 
			
		||||
    delete [] pStart;
 | 
			
		||||
    return sResult;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
 | 
			
		||||
std::string UTF16ToUTF8(const std::wstring& input)
 | 
			
		||||
{
 | 
			
		||||
	auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), nullptr, 0, nullptr, nullptr);
 | 
			
		||||
    auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), nullptr, 0, nullptr, nullptr);
 | 
			
		||||
 | 
			
		||||
	std::string output;
 | 
			
		||||
	output.resize(size);
 | 
			
		||||
    std::string output;
 | 
			
		||||
    output.resize(size);
 | 
			
		||||
 | 
			
		||||
	if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr))
 | 
			
		||||
		output.clear();
 | 
			
		||||
    if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr))
 | 
			
		||||
        output.clear();
 | 
			
		||||
 | 
			
		||||
	return output;
 | 
			
		||||
    return output;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::wstring CPToUTF16(u32 code_page, const std::string& input)
 | 
			
		||||
{
 | 
			
		||||
	auto const size = MultiByteToWideChar(code_page, 0, input.data(), input.size(), nullptr, 0);
 | 
			
		||||
    auto const size = MultiByteToWideChar(code_page, 0, input.data(), input.size(), nullptr, 0);
 | 
			
		||||
 | 
			
		||||
	std::wstring output;
 | 
			
		||||
	output.resize(size);
 | 
			
		||||
    std::wstring output;
 | 
			
		||||
    output.resize(size);
 | 
			
		||||
 | 
			
		||||
	if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size()))
 | 
			
		||||
		output.clear();
 | 
			
		||||
    if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size()))
 | 
			
		||||
        output.clear();
 | 
			
		||||
 | 
			
		||||
	return output;
 | 
			
		||||
    return output;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::wstring UTF8ToUTF16(const std::string& input)
 | 
			
		||||
{
 | 
			
		||||
	return CPToUTF16(CP_UTF8, input);
 | 
			
		||||
    return CPToUTF16(CP_UTF8, input);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string SHIFTJISToUTF8(const std::string& input)
 | 
			
		||||
{
 | 
			
		||||
	return UTF16ToUTF8(CPToUTF16(932, input));
 | 
			
		||||
    return UTF16ToUTF8(CPToUTF16(932, input));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string CP1252ToUTF8(const std::string& input)
 | 
			
		||||
{
 | 
			
		||||
	return UTF16ToUTF8(CPToUTF16(1252, input));
 | 
			
		||||
    return UTF16ToUTF8(CPToUTF16(1252, input));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
@@ -449,83 +449,83 @@ std::string CP1252ToUTF8(const std::string& input)
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& input)
 | 
			
		||||
{
 | 
			
		||||
	std::string result;
 | 
			
		||||
    std::string result;
 | 
			
		||||
 | 
			
		||||
	iconv_t const conv_desc = iconv_open("UTF-8", fromcode);
 | 
			
		||||
	if ((iconv_t)-1 == conv_desc)
 | 
			
		||||
	{
 | 
			
		||||
		ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		size_t const in_bytes = sizeof(T) * input.size();
 | 
			
		||||
		size_t const out_buffer_size = 4 * in_bytes;
 | 
			
		||||
    iconv_t const conv_desc = iconv_open("UTF-8", fromcode);
 | 
			
		||||
    if ((iconv_t)-1 == conv_desc)
 | 
			
		||||
    {
 | 
			
		||||
        ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno));
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        size_t const in_bytes = sizeof(T) * input.size();
 | 
			
		||||
        size_t const out_buffer_size = 4 * in_bytes;
 | 
			
		||||
 | 
			
		||||
		std::string out_buffer;
 | 
			
		||||
		out_buffer.resize(out_buffer_size);
 | 
			
		||||
        std::string out_buffer;
 | 
			
		||||
        out_buffer.resize(out_buffer_size);
 | 
			
		||||
 | 
			
		||||
		auto src_buffer = &input[0];
 | 
			
		||||
		size_t src_bytes = in_bytes;
 | 
			
		||||
		auto dst_buffer = &out_buffer[0];
 | 
			
		||||
		size_t dst_bytes = out_buffer.size();
 | 
			
		||||
        auto src_buffer = &input[0];
 | 
			
		||||
        size_t src_bytes = in_bytes;
 | 
			
		||||
        auto dst_buffer = &out_buffer[0];
 | 
			
		||||
        size_t dst_bytes = out_buffer.size();
 | 
			
		||||
 | 
			
		||||
		while (src_bytes != 0)
 | 
			
		||||
		{
 | 
			
		||||
			size_t const iconv_result = iconv(conv_desc, (char**)(&src_buffer), &src_bytes,
 | 
			
		||||
				&dst_buffer, &dst_bytes);
 | 
			
		||||
        while (src_bytes != 0)
 | 
			
		||||
        {
 | 
			
		||||
            size_t const iconv_result = iconv(conv_desc, (char**)(&src_buffer), &src_bytes,
 | 
			
		||||
                &dst_buffer, &dst_bytes);
 | 
			
		||||
 | 
			
		||||
			if ((size_t)-1 == iconv_result)
 | 
			
		||||
			{
 | 
			
		||||
				if (EILSEQ == errno || EINVAL == errno)
 | 
			
		||||
				{
 | 
			
		||||
					// Try to skip the bad character
 | 
			
		||||
					if (src_bytes != 0)
 | 
			
		||||
					{
 | 
			
		||||
						--src_bytes;
 | 
			
		||||
						++src_buffer;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno));
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
            if ((size_t)-1 == iconv_result)
 | 
			
		||||
            {
 | 
			
		||||
                if (EILSEQ == errno || EINVAL == errno)
 | 
			
		||||
                {
 | 
			
		||||
                    // Try to skip the bad character
 | 
			
		||||
                    if (src_bytes != 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        --src_bytes;
 | 
			
		||||
                        ++src_buffer;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno));
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		out_buffer.resize(out_buffer_size - dst_bytes);
 | 
			
		||||
		out_buffer.swap(result);
 | 
			
		||||
		
 | 
			
		||||
		iconv_close(conv_desc);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return result;
 | 
			
		||||
        out_buffer.resize(out_buffer_size - dst_bytes);
 | 
			
		||||
        out_buffer.swap(result);
 | 
			
		||||
        
 | 
			
		||||
        iconv_close(conv_desc);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string CP1252ToUTF8(const std::string& input)
 | 
			
		||||
{
 | 
			
		||||
	//return CodeToUTF8("CP1252//TRANSLIT", input);
 | 
			
		||||
	//return CodeToUTF8("CP1252//IGNORE", input);
 | 
			
		||||
	return CodeToUTF8("CP1252", input);
 | 
			
		||||
    //return CodeToUTF8("CP1252//TRANSLIT", input);
 | 
			
		||||
    //return CodeToUTF8("CP1252//IGNORE", input);
 | 
			
		||||
    return CodeToUTF8("CP1252", input);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string SHIFTJISToUTF8(const std::string& input)
 | 
			
		||||
{
 | 
			
		||||
	//return CodeToUTF8("CP932", input);
 | 
			
		||||
	return CodeToUTF8("SJIS", input);
 | 
			
		||||
    //return CodeToUTF8("CP932", input);
 | 
			
		||||
    return CodeToUTF8("SJIS", input);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string UTF16ToUTF8(const std::wstring& input)
 | 
			
		||||
{
 | 
			
		||||
	std::string result =
 | 
			
		||||
	//	CodeToUTF8("UCS-2", input);
 | 
			
		||||
	//	CodeToUTF8("UCS-2LE", input);
 | 
			
		||||
	//	CodeToUTF8("UTF-16", input);
 | 
			
		||||
		CodeToUTF8("UTF-16LE", input);
 | 
			
		||||
    std::string result =
 | 
			
		||||
    //    CodeToUTF8("UCS-2", input);
 | 
			
		||||
    //    CodeToUTF8("UCS-2LE", input);
 | 
			
		||||
    //    CodeToUTF8("UTF-16", input);
 | 
			
		||||
        CodeToUTF8("UTF-16LE", input);
 | 
			
		||||
 | 
			
		||||
	// TODO: why is this needed?
 | 
			
		||||
	result.erase(std::remove(result.begin(), result.end(), 0x00), result.end());
 | 
			
		||||
	return result;
 | 
			
		||||
    // TODO: why is this needed?
 | 
			
		||||
    result.erase(std::remove(result.begin(), result.end(), 0x00), result.end());
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -21,10 +21,10 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar
 | 
			
		||||
template<size_t Count>
 | 
			
		||||
inline void CharArrayFromFormat(char (& out)[Count], const char* format, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list args;
 | 
			
		||||
	va_start(args, format);
 | 
			
		||||
	CharArrayFromFormatV(out, Count, format, args);
 | 
			
		||||
	va_end(args);
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start(args, format);
 | 
			
		||||
    CharArrayFromFormatV(out, Count, format, args);
 | 
			
		||||
    va_end(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Good
 | 
			
		||||
@@ -37,15 +37,15 @@ std::string StripQuotes(const std::string &s);
 | 
			
		||||
template <typename I>
 | 
			
		||||
std::string ThousandSeparate(I value, int spaces = 0)
 | 
			
		||||
{
 | 
			
		||||
	std::ostringstream oss;
 | 
			
		||||
    std::ostringstream oss;
 | 
			
		||||
 | 
			
		||||
// std::locale("") seems to be broken on many platforms
 | 
			
		||||
#if defined _WIN32 || (defined __linux__ && !defined __clang__)
 | 
			
		||||
	oss.imbue(std::locale(""));
 | 
			
		||||
    oss.imbue(std::locale(""));
 | 
			
		||||
#endif
 | 
			
		||||
	oss << std::setw(spaces) << value;
 | 
			
		||||
    oss << std::setw(spaces) << value;
 | 
			
		||||
 | 
			
		||||
	return oss.str();
 | 
			
		||||
    return oss.str();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string StringFromInt(int value);
 | 
			
		||||
@@ -57,16 +57,16 @@ bool TryParse(const std::string &str, u32 *output);
 | 
			
		||||
template <typename N>
 | 
			
		||||
static bool TryParse(const std::string &str, N *const output)
 | 
			
		||||
{
 | 
			
		||||
	std::istringstream iss(str);
 | 
			
		||||
	
 | 
			
		||||
	N tmp = 0;
 | 
			
		||||
	if (iss >> tmp)
 | 
			
		||||
	{
 | 
			
		||||
		*output = tmp;
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		return false;
 | 
			
		||||
    std::istringstream iss(str);
 | 
			
		||||
    
 | 
			
		||||
    N tmp = 0;
 | 
			
		||||
    if (iss >> tmp)
 | 
			
		||||
    {
 | 
			
		||||
        *output = tmp;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: kill this
 | 
			
		||||
 
 | 
			
		||||
@@ -63,426 +63,426 @@
 | 
			
		||||
 | 
			
		||||
template <typename T, typename F>
 | 
			
		||||
struct swap_struct_t {
 | 
			
		||||
	typedef swap_struct_t<T, F> swapped_t;
 | 
			
		||||
    typedef swap_struct_t<T, F> swapped_t;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	T value;
 | 
			
		||||
    T value;
 | 
			
		||||
 | 
			
		||||
	static T swap(T v) {
 | 
			
		||||
		return F::swap(v);
 | 
			
		||||
	}
 | 
			
		||||
    static T swap(T v) {
 | 
			
		||||
        return F::swap(v);
 | 
			
		||||
    }
 | 
			
		||||
public:
 | 
			
		||||
	T const swap() const {
 | 
			
		||||
		return swap(value);
 | 
			
		||||
    T const swap() const {
 | 
			
		||||
        return swap(value);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	swap_struct_t() : value((T)0) {}
 | 
			
		||||
	swap_struct_t(const T &v): value(swap(v)) {}
 | 
			
		||||
    }
 | 
			
		||||
    swap_struct_t() : value((T)0) {}
 | 
			
		||||
    swap_struct_t(const T &v): value(swap(v)) {}
 | 
			
		||||
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t& operator=(const S &source) {
 | 
			
		||||
		value = swap((T)source);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t& operator=(const S &source) {
 | 
			
		||||
        value = swap((T)source);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	operator long() const { return (long)swap(); }	
 | 
			
		||||
	operator s8() const { return (s8)swap(); }
 | 
			
		||||
	operator u8() const { return (u8)swap(); }
 | 
			
		||||
	operator s16() const { return (s16)swap(); }
 | 
			
		||||
	operator u16() const { return (u16)swap(); }
 | 
			
		||||
	operator s32() const { return (s32)swap(); }
 | 
			
		||||
	operator u32() const { return (u32)swap(); }
 | 
			
		||||
	operator s64() const { return (s64)swap(); }
 | 
			
		||||
	operator u64() const { return (u64)swap(); }
 | 
			
		||||
	operator float() const { return (float)swap(); }
 | 
			
		||||
	operator double() const { return (double)swap(); }
 | 
			
		||||
    operator long() const { return (long)swap(); }    
 | 
			
		||||
    operator s8() const { return (s8)swap(); }
 | 
			
		||||
    operator u8() const { return (u8)swap(); }
 | 
			
		||||
    operator s16() const { return (s16)swap(); }
 | 
			
		||||
    operator u16() const { return (u16)swap(); }
 | 
			
		||||
    operator s32() const { return (s32)swap(); }
 | 
			
		||||
    operator u32() const { return (u32)swap(); }
 | 
			
		||||
    operator s64() const { return (s64)swap(); }
 | 
			
		||||
    operator u64() const { return (u64)swap(); }
 | 
			
		||||
    operator float() const { return (float)swap(); }
 | 
			
		||||
    operator double() const { return (double)swap(); }
 | 
			
		||||
 | 
			
		||||
	// +v
 | 
			
		||||
	swapped_t operator +() const {
 | 
			
		||||
		return +swap();
 | 
			
		||||
	}
 | 
			
		||||
	// -v
 | 
			
		||||
	swapped_t operator -() const {
 | 
			
		||||
		return -swap();
 | 
			
		||||
	}
 | 
			
		||||
    // +v
 | 
			
		||||
    swapped_t operator +() const {
 | 
			
		||||
        return +swap();
 | 
			
		||||
    }
 | 
			
		||||
    // -v
 | 
			
		||||
    swapped_t operator -() const {
 | 
			
		||||
        return -swap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// v / 5
 | 
			
		||||
	swapped_t operator/(const swapped_t &i) const {
 | 
			
		||||
		return swap() / i.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t operator/(const S &i) const {
 | 
			
		||||
		return swap() / i;
 | 
			
		||||
	}
 | 
			
		||||
    // v / 5
 | 
			
		||||
    swapped_t operator/(const swapped_t &i) const {
 | 
			
		||||
        return swap() / i.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t operator/(const S &i) const {
 | 
			
		||||
        return swap() / i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// v * 5
 | 
			
		||||
	swapped_t operator*(const swapped_t &i) const {
 | 
			
		||||
		return swap() * i.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t operator*(const S &i) const {
 | 
			
		||||
		return swap() * i;
 | 
			
		||||
	}
 | 
			
		||||
    // v * 5
 | 
			
		||||
    swapped_t operator*(const swapped_t &i) const {
 | 
			
		||||
        return swap() * i.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t operator*(const S &i) const {
 | 
			
		||||
        return swap() * i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// v + 5
 | 
			
		||||
	swapped_t operator+(const swapped_t &i) const {
 | 
			
		||||
		return swap() + i.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t operator+(const S &i) const {
 | 
			
		||||
		return swap() + (T)i;
 | 
			
		||||
	}
 | 
			
		||||
	// v - 5
 | 
			
		||||
	swapped_t operator-(const swapped_t &i) const {
 | 
			
		||||
		return swap() - i.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t operator-(const S &i) const {
 | 
			
		||||
		return swap() - (T)i;
 | 
			
		||||
	}
 | 
			
		||||
    // v + 5
 | 
			
		||||
    swapped_t operator+(const swapped_t &i) const {
 | 
			
		||||
        return swap() + i.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t operator+(const S &i) const {
 | 
			
		||||
        return swap() + (T)i;
 | 
			
		||||
    }
 | 
			
		||||
    // v - 5
 | 
			
		||||
    swapped_t operator-(const swapped_t &i) const {
 | 
			
		||||
        return swap() - i.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t operator-(const S &i) const {
 | 
			
		||||
        return swap() - (T)i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// v += 5
 | 
			
		||||
	swapped_t& operator+=(const swapped_t &i) {
 | 
			
		||||
		value = swap(swap() + i.swap());
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t& operator+=(const S &i) {
 | 
			
		||||
		value = swap(swap() + (T)i);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	// v -= 5
 | 
			
		||||
	swapped_t& operator-=(const swapped_t &i) {
 | 
			
		||||
		value = swap(swap() - i.swap());
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t& operator-=(const S &i) {
 | 
			
		||||
		value = swap(swap() - (T)i);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
    // v += 5
 | 
			
		||||
    swapped_t& operator+=(const swapped_t &i) {
 | 
			
		||||
        value = swap(swap() + i.swap());
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t& operator+=(const S &i) {
 | 
			
		||||
        value = swap(swap() + (T)i);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    // v -= 5
 | 
			
		||||
    swapped_t& operator-=(const swapped_t &i) {
 | 
			
		||||
        value = swap(swap() - i.swap());
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t& operator-=(const S &i) {
 | 
			
		||||
        value = swap(swap() - (T)i);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// ++v
 | 
			
		||||
	swapped_t& operator++() {
 | 
			
		||||
		value = swap(swap()+1);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	// --v
 | 
			
		||||
	swapped_t& operator--()  {
 | 
			
		||||
		value = swap(swap()-1);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
    // ++v
 | 
			
		||||
    swapped_t& operator++() {
 | 
			
		||||
        value = swap(swap()+1);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    // --v
 | 
			
		||||
    swapped_t& operator--()  {
 | 
			
		||||
        value = swap(swap()-1);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// v++
 | 
			
		||||
	swapped_t operator++(int) {
 | 
			
		||||
		swapped_t old = *this;
 | 
			
		||||
		value = swap(swap()+1);
 | 
			
		||||
		return old;
 | 
			
		||||
	}
 | 
			
		||||
	// v--
 | 
			
		||||
	swapped_t operator--(int) {
 | 
			
		||||
		swapped_t old = *this;
 | 
			
		||||
		value = swap(swap()-1);
 | 
			
		||||
		return old;
 | 
			
		||||
	}
 | 
			
		||||
	// Comparaison
 | 
			
		||||
	// v == i
 | 
			
		||||
	bool operator==(const swapped_t &i) const {
 | 
			
		||||
		return swap() == i.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	bool operator==(const S &i) const {
 | 
			
		||||
		return swap() == i;
 | 
			
		||||
	}
 | 
			
		||||
    // v++
 | 
			
		||||
    swapped_t operator++(int) {
 | 
			
		||||
        swapped_t old = *this;
 | 
			
		||||
        value = swap(swap()+1);
 | 
			
		||||
        return old;
 | 
			
		||||
    }
 | 
			
		||||
    // v--
 | 
			
		||||
    swapped_t operator--(int) {
 | 
			
		||||
        swapped_t old = *this;
 | 
			
		||||
        value = swap(swap()-1);
 | 
			
		||||
        return old;
 | 
			
		||||
    }
 | 
			
		||||
    // Comparaison
 | 
			
		||||
    // v == i
 | 
			
		||||
    bool operator==(const swapped_t &i) const {
 | 
			
		||||
        return swap() == i.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    bool operator==(const S &i) const {
 | 
			
		||||
        return swap() == i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// v != i
 | 
			
		||||
	bool operator!=(const swapped_t &i) const {
 | 
			
		||||
		return swap() != i.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	bool operator!=(const S &i) const {
 | 
			
		||||
		return swap() != i;
 | 
			
		||||
	}
 | 
			
		||||
    // v != i
 | 
			
		||||
    bool operator!=(const swapped_t &i) const {
 | 
			
		||||
        return swap() != i.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    bool operator!=(const S &i) const {
 | 
			
		||||
        return swap() != i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// v > i
 | 
			
		||||
	bool operator>(const swapped_t &i) const {
 | 
			
		||||
		return swap() > i.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	bool operator>(const S &i) const {
 | 
			
		||||
		return swap() > i;
 | 
			
		||||
	}
 | 
			
		||||
    // v > i
 | 
			
		||||
    bool operator>(const swapped_t &i) const {
 | 
			
		||||
        return swap() > i.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    bool operator>(const S &i) const {
 | 
			
		||||
        return swap() > i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// v < i
 | 
			
		||||
	bool operator<(const swapped_t &i) const {
 | 
			
		||||
		return swap() < i.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	bool operator<(const S &i) const {
 | 
			
		||||
		return swap() < i;
 | 
			
		||||
	}
 | 
			
		||||
    // v < i
 | 
			
		||||
    bool operator<(const swapped_t &i) const {
 | 
			
		||||
        return swap() < i.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    bool operator<(const S &i) const {
 | 
			
		||||
        return swap() < i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// v >= i
 | 
			
		||||
	bool operator>=(const swapped_t &i) const {
 | 
			
		||||
		return swap() >= i.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	bool operator>=(const S &i) const {
 | 
			
		||||
		return swap() >= i;
 | 
			
		||||
	}
 | 
			
		||||
    // v >= i
 | 
			
		||||
    bool operator>=(const swapped_t &i) const {
 | 
			
		||||
        return swap() >= i.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    bool operator>=(const S &i) const {
 | 
			
		||||
        return swap() >= i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// v <= i
 | 
			
		||||
	bool operator<=(const swapped_t &i) const {
 | 
			
		||||
		return swap() <= i.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	bool operator<=(const S &i) const {
 | 
			
		||||
		return swap() <= i;
 | 
			
		||||
	}
 | 
			
		||||
    // v <= i
 | 
			
		||||
    bool operator<=(const swapped_t &i) const {
 | 
			
		||||
        return swap() <= i.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    bool operator<=(const S &i) const {
 | 
			
		||||
        return swap() <= i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// logical
 | 
			
		||||
	swapped_t operator !() const {
 | 
			
		||||
		return !swap();
 | 
			
		||||
	}
 | 
			
		||||
    // logical
 | 
			
		||||
    swapped_t operator !() const {
 | 
			
		||||
        return !swap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// bitmath
 | 
			
		||||
	swapped_t operator ~() const {
 | 
			
		||||
		return ~swap();
 | 
			
		||||
	}
 | 
			
		||||
    // bitmath
 | 
			
		||||
    swapped_t operator ~() const {
 | 
			
		||||
        return ~swap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	swapped_t operator &(const swapped_t &b) const {
 | 
			
		||||
		return swap() & b.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t operator &(const S &b) const {
 | 
			
		||||
		return swap() & b;
 | 
			
		||||
	}
 | 
			
		||||
	swapped_t& operator &=(const swapped_t &b) {
 | 
			
		||||
		value = swap(swap() & b.swap());
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t& operator &=(const S b) {
 | 
			
		||||
		value = swap(swap() & b);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
    swapped_t operator &(const swapped_t &b) const {
 | 
			
		||||
        return swap() & b.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t operator &(const S &b) const {
 | 
			
		||||
        return swap() & b;
 | 
			
		||||
    }
 | 
			
		||||
    swapped_t& operator &=(const swapped_t &b) {
 | 
			
		||||
        value = swap(swap() & b.swap());
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t& operator &=(const S b) {
 | 
			
		||||
        value = swap(swap() & b);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	swapped_t operator |(const swapped_t &b) const {
 | 
			
		||||
		return swap() | b.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t operator |(const S &b) const {
 | 
			
		||||
		return swap() | b;
 | 
			
		||||
	}
 | 
			
		||||
	swapped_t& operator |=(const swapped_t &b) {
 | 
			
		||||
		value = swap(swap() | b.swap());
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t& operator |=(const S &b) {
 | 
			
		||||
		value = swap(swap() | b);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
    swapped_t operator |(const swapped_t &b) const {
 | 
			
		||||
        return swap() | b.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t operator |(const S &b) const {
 | 
			
		||||
        return swap() | b;
 | 
			
		||||
    }
 | 
			
		||||
    swapped_t& operator |=(const swapped_t &b) {
 | 
			
		||||
        value = swap(swap() | b.swap());
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t& operator |=(const S &b) {
 | 
			
		||||
        value = swap(swap() | b);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	swapped_t operator ^(const swapped_t &b) const {
 | 
			
		||||
		return swap() ^ b.swap();
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t operator ^(const S &b) const {
 | 
			
		||||
		return swap() ^ b;
 | 
			
		||||
	}
 | 
			
		||||
	swapped_t& operator ^=(const swapped_t &b) {
 | 
			
		||||
		value = swap(swap() ^ b.swap());
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t& operator ^=(const S &b) {
 | 
			
		||||
		value = swap(swap() ^ b);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
    swapped_t operator ^(const swapped_t &b) const {
 | 
			
		||||
        return swap() ^ b.swap();
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t operator ^(const S &b) const {
 | 
			
		||||
        return swap() ^ b;
 | 
			
		||||
    }
 | 
			
		||||
    swapped_t& operator ^=(const swapped_t &b) {
 | 
			
		||||
        value = swap(swap() ^ b.swap());
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t& operator ^=(const S &b) {
 | 
			
		||||
        value = swap(swap() ^ b);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t operator <<(const S &b) const {
 | 
			
		||||
		return swap() << b;
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t& operator <<=(const S &b) const {
 | 
			
		||||
		value = swap(swap() << b);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t operator <<(const S &b) const {
 | 
			
		||||
        return swap() << b;
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t& operator <<=(const S &b) const {
 | 
			
		||||
        value = swap(swap() << b);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t operator >>(const S &b) const {
 | 
			
		||||
		return swap() >> b;
 | 
			
		||||
	}
 | 
			
		||||
	template <typename S>
 | 
			
		||||
	swapped_t& operator >>=(const S &b) const {
 | 
			
		||||
		value = swap(swap() >> b);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t operator >>(const S &b) const {
 | 
			
		||||
        return swap() >> b;
 | 
			
		||||
    }
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    swapped_t& operator >>=(const S &b) const {
 | 
			
		||||
        value = swap(swap() >> b);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// Member
 | 
			
		||||
	/** todo **/
 | 
			
		||||
    // Member
 | 
			
		||||
    /** todo **/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// Arithmetics
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend S operator+(const S &p, const swapped_t v);
 | 
			
		||||
    // Arithmetics
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend S operator+(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend S operator-(const S &p, const swapped_t v);
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend S operator-(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend S operator/(const S &p, const swapped_t v);
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend S operator/(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend S operator*(const S &p, const swapped_t v);
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend S operator*(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend S operator%(const S &p, const swapped_t v);
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend S operator%(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	// Arithmetics + assignements
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend S operator+=(const S &p, const swapped_t v);
 | 
			
		||||
    // Arithmetics + assignements
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend S operator+=(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend S operator-=(const S &p, const swapped_t v);
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend S operator-=(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	// Bitmath
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend S operator&(const S &p, const swapped_t v);
 | 
			
		||||
    // Bitmath
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend S operator&(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	// Comparison
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend bool operator<(const S &p, const swapped_t v);
 | 
			
		||||
    // Comparison
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend bool operator<(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend bool operator>(const S &p, const swapped_t v);
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend bool operator>(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend bool operator<=(const S &p, const swapped_t v);
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend bool operator<=(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend bool operator>=(const S &p, const swapped_t v);
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend bool operator>=(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend bool operator!=(const S &p, const swapped_t v);
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend bool operator!=(const S &p, const swapped_t v);
 | 
			
		||||
 | 
			
		||||
	template <typename S, typename T2, typename F2>
 | 
			
		||||
	friend bool operator==(const S &p, const swapped_t v);
 | 
			
		||||
    template <typename S, typename T2, typename F2>
 | 
			
		||||
    friend bool operator==(const S &p, const swapped_t v);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Arithmetics
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
S operator+(const S &i, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return i + v.swap();
 | 
			
		||||
    return i + v.swap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
S operator-(const S &i, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return i - v.swap();
 | 
			
		||||
    return i - v.swap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
S operator/(const S &i, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return i / v.swap();
 | 
			
		||||
    return i / v.swap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
S operator*(const S &i, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return i * v.swap();
 | 
			
		||||
    return i * v.swap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
S operator%(const S &i, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return i % v.swap();
 | 
			
		||||
    return i % v.swap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Arithmetics + assignements
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
S &operator+=(S &i, const swap_struct_t<T, F> v) {
 | 
			
		||||
	i += v.swap();
 | 
			
		||||
	return i;
 | 
			
		||||
    i += v.swap();
 | 
			
		||||
    return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
S &operator-=(S &i, const swap_struct_t<T, F> v) {
 | 
			
		||||
	i -= v.swap();
 | 
			
		||||
	return i;
 | 
			
		||||
    i -= v.swap();
 | 
			
		||||
    return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Logical
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
S operator&(const S &i, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return i & v.swap();
 | 
			
		||||
    return i & v.swap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
S operator&(const swap_struct_t<T, F> v, const S &i) {
 | 
			
		||||
	return (S)(v.swap() & i);
 | 
			
		||||
    return (S)(v.swap() & i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Comparaison
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
bool operator<(const S &p, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return p < v.swap();
 | 
			
		||||
    return p < v.swap();
 | 
			
		||||
}
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
bool operator>(const S &p, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return p > v.swap();
 | 
			
		||||
    return p > v.swap();
 | 
			
		||||
}
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
bool operator<=(const S &p, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return p <= v.swap();
 | 
			
		||||
    return p <= v.swap();
 | 
			
		||||
}
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
bool operator>=(const S &p, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return p >= v.swap();
 | 
			
		||||
    return p >= v.swap();
 | 
			
		||||
}
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
bool operator!=(const S &p, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return p != v.swap();
 | 
			
		||||
    return p != v.swap();
 | 
			
		||||
}
 | 
			
		||||
template <typename S, typename T, typename F>
 | 
			
		||||
bool operator==(const S &p, const swap_struct_t<T, F> v) {
 | 
			
		||||
	return p == v.swap();
 | 
			
		||||
    return p == v.swap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct swap_64_t {
 | 
			
		||||
	static T swap(T x) {
 | 
			
		||||
		return (T)bswap64(*(u64 *)&x);
 | 
			
		||||
	}
 | 
			
		||||
    static T swap(T x) {
 | 
			
		||||
        return (T)bswap64(*(u64 *)&x);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct swap_32_t {
 | 
			
		||||
	static T swap(T x) {
 | 
			
		||||
		return (T)bswap32(*(u32 *)&x);
 | 
			
		||||
	}
 | 
			
		||||
    static T swap(T x) {
 | 
			
		||||
        return (T)bswap32(*(u32 *)&x);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct swap_16_t {
 | 
			
		||||
	static T swap(T x) {
 | 
			
		||||
		return (T)bswap16(*(u16 *)&x);
 | 
			
		||||
	}
 | 
			
		||||
    static T swap(T x) {
 | 
			
		||||
        return (T)bswap16(*(u16 *)&x);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct swap_float_t {
 | 
			
		||||
	static T swap(T x) {
 | 
			
		||||
		return (T)bswapf(*(float *)&x);
 | 
			
		||||
	}
 | 
			
		||||
    static T swap(T x) {
 | 
			
		||||
        return (T)bswapf(*(float *)&x);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct swap_double_t {
 | 
			
		||||
	static T swap(T x) {
 | 
			
		||||
		return (T)bswapd(*(double *)&x);
 | 
			
		||||
	}
 | 
			
		||||
    static T swap(T x) {
 | 
			
		||||
        return (T)bswapd(*(double *)&x);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if COMMON_LITTLE_ENDIAN
 | 
			
		||||
 
 | 
			
		||||
@@ -21,110 +21,110 @@ namespace Common
 | 
			
		||||
int CurrentThreadId()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	return GetCurrentThreadId();
 | 
			
		||||
    return GetCurrentThreadId();
 | 
			
		||||
#elif defined __APPLE__
 | 
			
		||||
	return mach_thread_self();
 | 
			
		||||
    return mach_thread_self();
 | 
			
		||||
#else
 | 
			
		||||
	return 0;
 | 
			
		||||
    return 0;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
	
 | 
			
		||||
    
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
 | 
			
		||||
void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask)
 | 
			
		||||
{
 | 
			
		||||
	SetThreadAffinityMask(thread, mask);
 | 
			
		||||
    SetThreadAffinityMask(thread, mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SetCurrentThreadAffinity(u32 mask)
 | 
			
		||||
{
 | 
			
		||||
	SetThreadAffinityMask(GetCurrentThread(), mask);
 | 
			
		||||
    SetThreadAffinityMask(GetCurrentThread(), mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Supporting functions
 | 
			
		||||
void SleepCurrentThread(int ms)
 | 
			
		||||
{
 | 
			
		||||
	Sleep(ms);
 | 
			
		||||
    Sleep(ms);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SwitchCurrentThread()
 | 
			
		||||
{
 | 
			
		||||
	SwitchToThread();
 | 
			
		||||
    SwitchToThread();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sets the debugger-visible name of the current thread.
 | 
			
		||||
// Uses undocumented (actually, it is now documented) trick.
 | 
			
		||||
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsdebug/html/vxtsksettingthreadname.asp
 | 
			
		||||
	
 | 
			
		||||
    
 | 
			
		||||
// This is implemented much nicer in upcoming msvc++, see:
 | 
			
		||||
// http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.100).aspx
 | 
			
		||||
void SetCurrentThreadName(const char* szThreadName)
 | 
			
		||||
{
 | 
			
		||||
	static const DWORD MS_VC_EXCEPTION = 0x406D1388;
 | 
			
		||||
    static const DWORD MS_VC_EXCEPTION = 0x406D1388;
 | 
			
		||||
 | 
			
		||||
	#pragma pack(push,8)
 | 
			
		||||
	struct THREADNAME_INFO
 | 
			
		||||
	{
 | 
			
		||||
		DWORD dwType; // must be 0x1000
 | 
			
		||||
		LPCSTR szName; // pointer to name (in user addr space)
 | 
			
		||||
		DWORD dwThreadID; // thread ID (-1=caller thread)
 | 
			
		||||
		DWORD dwFlags; // reserved for future use, must be zero
 | 
			
		||||
	} info;
 | 
			
		||||
	#pragma pack(pop)
 | 
			
		||||
    #pragma pack(push,8)
 | 
			
		||||
    struct THREADNAME_INFO
 | 
			
		||||
    {
 | 
			
		||||
        DWORD dwType; // must be 0x1000
 | 
			
		||||
        LPCSTR szName; // pointer to name (in user addr space)
 | 
			
		||||
        DWORD dwThreadID; // thread ID (-1=caller thread)
 | 
			
		||||
        DWORD dwFlags; // reserved for future use, must be zero
 | 
			
		||||
    } info;
 | 
			
		||||
    #pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
	info.dwType = 0x1000;
 | 
			
		||||
	info.szName = szThreadName;
 | 
			
		||||
	info.dwThreadID = -1; //dwThreadID;
 | 
			
		||||
	info.dwFlags = 0;
 | 
			
		||||
    info.dwType = 0x1000;
 | 
			
		||||
    info.szName = szThreadName;
 | 
			
		||||
    info.dwThreadID = -1; //dwThreadID;
 | 
			
		||||
    info.dwFlags = 0;
 | 
			
		||||
 | 
			
		||||
	__try
 | 
			
		||||
	{
 | 
			
		||||
		RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
 | 
			
		||||
	}
 | 
			
		||||
	__except(EXCEPTION_CONTINUE_EXECUTION)
 | 
			
		||||
	{}
 | 
			
		||||
    __try
 | 
			
		||||
    {
 | 
			
		||||
        RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
 | 
			
		||||
    }
 | 
			
		||||
    __except(EXCEPTION_CONTINUE_EXECUTION)
 | 
			
		||||
    {}
 | 
			
		||||
}
 | 
			
		||||
	
 | 
			
		||||
    
 | 
			
		||||
#else // !WIN32, so must be POSIX threads
 | 
			
		||||
 | 
			
		||||
void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask)
 | 
			
		||||
{
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
	thread_policy_set(pthread_mach_thread_np(thread),
 | 
			
		||||
		THREAD_AFFINITY_POLICY, (integer_t *)&mask, 1);
 | 
			
		||||
    thread_policy_set(pthread_mach_thread_np(thread),
 | 
			
		||||
        THREAD_AFFINITY_POLICY, (integer_t *)&mask, 1);
 | 
			
		||||
#elif (defined __linux__ || defined BSD4_4) && !(defined ANDROID)
 | 
			
		||||
	cpu_set_t cpu_set;
 | 
			
		||||
	CPU_ZERO(&cpu_set);
 | 
			
		||||
    cpu_set_t cpu_set;
 | 
			
		||||
    CPU_ZERO(&cpu_set);
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i != sizeof(mask) * 8; ++i)
 | 
			
		||||
		if ((mask >> i) & 1)
 | 
			
		||||
			CPU_SET(i, &cpu_set);
 | 
			
		||||
    for (int i = 0; i != sizeof(mask) * 8; ++i)
 | 
			
		||||
        if ((mask >> i) & 1)
 | 
			
		||||
            CPU_SET(i, &cpu_set);
 | 
			
		||||
 | 
			
		||||
	pthread_setaffinity_np(thread, sizeof(cpu_set), &cpu_set);
 | 
			
		||||
    pthread_setaffinity_np(thread, sizeof(cpu_set), &cpu_set);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SetCurrentThreadAffinity(u32 mask)
 | 
			
		||||
{
 | 
			
		||||
	SetThreadAffinity(pthread_self(), mask);
 | 
			
		||||
    SetThreadAffinity(pthread_self(), mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SleepCurrentThread(int ms)
 | 
			
		||||
{
 | 
			
		||||
	usleep(1000 * ms);
 | 
			
		||||
    usleep(1000 * ms);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SwitchCurrentThread()
 | 
			
		||||
{
 | 
			
		||||
	usleep(1000 * 1);
 | 
			
		||||
    usleep(1000 * 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SetCurrentThreadName(const char* szThreadName)
 | 
			
		||||
{
 | 
			
		||||
#ifdef __APPLE__
 | 
			
		||||
	pthread_setname_np(szThreadName);
 | 
			
		||||
    pthread_setname_np(szThreadName);
 | 
			
		||||
#else
 | 
			
		||||
	pthread_setname_np(pthread_self(), szThreadName);
 | 
			
		||||
    pthread_setname_np(pthread_self(), szThreadName);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -32,125 +32,125 @@ int CurrentThreadId();
 | 
			
		||||
 | 
			
		||||
void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask);
 | 
			
		||||
void SetCurrentThreadAffinity(u32 mask);
 | 
			
		||||
	
 | 
			
		||||
    
 | 
			
		||||
class Event
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	Event()
 | 
			
		||||
		: is_set(false)
 | 
			
		||||
	{};
 | 
			
		||||
    Event()
 | 
			
		||||
        : is_set(false)
 | 
			
		||||
    {};
 | 
			
		||||
 | 
			
		||||
	void Set()
 | 
			
		||||
	{
 | 
			
		||||
		std::lock_guard<std::mutex> lk(m_mutex);
 | 
			
		||||
		if (!is_set)
 | 
			
		||||
		{
 | 
			
		||||
			is_set = true;
 | 
			
		||||
			m_condvar.notify_one();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    void Set()
 | 
			
		||||
    {
 | 
			
		||||
        std::lock_guard<std::mutex> lk(m_mutex);
 | 
			
		||||
        if (!is_set)
 | 
			
		||||
        {
 | 
			
		||||
            is_set = true;
 | 
			
		||||
            m_condvar.notify_one();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void Wait()
 | 
			
		||||
	{
 | 
			
		||||
		std::unique_lock<std::mutex> lk(m_mutex);
 | 
			
		||||
		m_condvar.wait(lk, IsSet(this));
 | 
			
		||||
		is_set = false;
 | 
			
		||||
	}
 | 
			
		||||
    void Wait()
 | 
			
		||||
    {
 | 
			
		||||
        std::unique_lock<std::mutex> lk(m_mutex);
 | 
			
		||||
        m_condvar.wait(lk, IsSet(this));
 | 
			
		||||
        is_set = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	void Reset()
 | 
			
		||||
	{
 | 
			
		||||
		std::unique_lock<std::mutex> lk(m_mutex);
 | 
			
		||||
		// no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration
 | 
			
		||||
		is_set = false;
 | 
			
		||||
	}
 | 
			
		||||
    void Reset()
 | 
			
		||||
    {
 | 
			
		||||
        std::unique_lock<std::mutex> lk(m_mutex);
 | 
			
		||||
        // no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration
 | 
			
		||||
        is_set = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	class IsSet
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		IsSet(const Event* ev)
 | 
			
		||||
			: m_event(ev)
 | 
			
		||||
		{}
 | 
			
		||||
    class IsSet
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        IsSet(const Event* ev)
 | 
			
		||||
            : m_event(ev)
 | 
			
		||||
        {}
 | 
			
		||||
 | 
			
		||||
		bool operator()()
 | 
			
		||||
		{
 | 
			
		||||
			return m_event->is_set;
 | 
			
		||||
		}
 | 
			
		||||
        bool operator()()
 | 
			
		||||
        {
 | 
			
		||||
            return m_event->is_set;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		const Event* const m_event;
 | 
			
		||||
	};
 | 
			
		||||
    private:
 | 
			
		||||
        const Event* const m_event;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
	volatile bool is_set;
 | 
			
		||||
	std::condition_variable m_condvar;
 | 
			
		||||
	std::mutex m_mutex;
 | 
			
		||||
    volatile bool is_set;
 | 
			
		||||
    std::condition_variable m_condvar;
 | 
			
		||||
    std::mutex m_mutex;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// TODO: doesn't work on windows with (count > 2)
 | 
			
		||||
class Barrier
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	Barrier(size_t count)
 | 
			
		||||
		: m_count(count), m_waiting(0)
 | 
			
		||||
	{}
 | 
			
		||||
    Barrier(size_t count)
 | 
			
		||||
        : m_count(count), m_waiting(0)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
	// block until "count" threads call Sync()
 | 
			
		||||
	bool Sync()
 | 
			
		||||
	{
 | 
			
		||||
		std::unique_lock<std::mutex> lk(m_mutex);
 | 
			
		||||
    // block until "count" threads call Sync()
 | 
			
		||||
    bool Sync()
 | 
			
		||||
    {
 | 
			
		||||
        std::unique_lock<std::mutex> lk(m_mutex);
 | 
			
		||||
 | 
			
		||||
		// TODO: broken when next round of Sync()s
 | 
			
		||||
		// is entered before all waiting threads return from the notify_all
 | 
			
		||||
        // TODO: broken when next round of Sync()s
 | 
			
		||||
        // is entered before all waiting threads return from the notify_all
 | 
			
		||||
 | 
			
		||||
		if (m_count == ++m_waiting)
 | 
			
		||||
		{
 | 
			
		||||
			m_waiting = 0;
 | 
			
		||||
			m_condvar.notify_all();
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			m_condvar.wait(lk, IsDoneWating(this));
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
        if (m_count == ++m_waiting)
 | 
			
		||||
        {
 | 
			
		||||
            m_waiting = 0;
 | 
			
		||||
            m_condvar.notify_all();
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            m_condvar.wait(lk, IsDoneWating(this));
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	class IsDoneWating
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		IsDoneWating(const Barrier* bar)
 | 
			
		||||
			: m_bar(bar)
 | 
			
		||||
		{}
 | 
			
		||||
    class IsDoneWating
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        IsDoneWating(const Barrier* bar)
 | 
			
		||||
            : m_bar(bar)
 | 
			
		||||
        {}
 | 
			
		||||
 | 
			
		||||
		bool operator()()
 | 
			
		||||
		{
 | 
			
		||||
			return (0 == m_bar->m_waiting);
 | 
			
		||||
		}
 | 
			
		||||
        bool operator()()
 | 
			
		||||
        {
 | 
			
		||||
            return (0 == m_bar->m_waiting);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		const Barrier* const m_bar;
 | 
			
		||||
	};
 | 
			
		||||
    private:
 | 
			
		||||
        const Barrier* const m_bar;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
	std::condition_variable m_condvar;
 | 
			
		||||
	std::mutex m_mutex;
 | 
			
		||||
	const size_t m_count;
 | 
			
		||||
	volatile size_t m_waiting;
 | 
			
		||||
    std::condition_variable m_condvar;
 | 
			
		||||
    std::mutex m_mutex;
 | 
			
		||||
    const size_t m_count;
 | 
			
		||||
    volatile size_t m_waiting;
 | 
			
		||||
};
 | 
			
		||||
	
 | 
			
		||||
    
 | 
			
		||||
void SleepCurrentThread(int ms);
 | 
			
		||||
void SwitchCurrentThread();	// On Linux, this is equal to sleep 1ms
 | 
			
		||||
void SwitchCurrentThread();    // On Linux, this is equal to sleep 1ms
 | 
			
		||||
 | 
			
		||||
// Use this function during a spin-wait to make the current thread
 | 
			
		||||
// relax while another thread is working. This may be more efficient
 | 
			
		||||
// than using events because event functions use kernel calls.
 | 
			
		||||
inline void YieldCPU()
 | 
			
		||||
{
 | 
			
		||||
	std::this_thread::yield();
 | 
			
		||||
    std::this_thread::yield();
 | 
			
		||||
}
 | 
			
		||||
	
 | 
			
		||||
    
 | 
			
		||||
void SetCurrentThreadName(const char *name);
 | 
			
		||||
	
 | 
			
		||||
    
 | 
			
		||||
} // namespace Common
 | 
			
		||||
 | 
			
		||||
#endif // _THREAD_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -24,23 +24,23 @@
 | 
			
		||||
 | 
			
		||||
class ThunkManager : public Gen::XCodeBlock
 | 
			
		||||
{
 | 
			
		||||
	std::map<void *, const u8 *> thunks;
 | 
			
		||||
    std::map<void *, const u8 *> thunks;
 | 
			
		||||
 | 
			
		||||
	const u8 *save_regs;
 | 
			
		||||
	const u8 *load_regs;
 | 
			
		||||
    const u8 *save_regs;
 | 
			
		||||
    const u8 *load_regs;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	ThunkManager() {
 | 
			
		||||
		Init();
 | 
			
		||||
	}
 | 
			
		||||
	~ThunkManager() {
 | 
			
		||||
		Shutdown();
 | 
			
		||||
	}
 | 
			
		||||
	void *ProtectFunction(void *function, int num_params);
 | 
			
		||||
    ThunkManager() {
 | 
			
		||||
        Init();
 | 
			
		||||
    }
 | 
			
		||||
    ~ThunkManager() {
 | 
			
		||||
        Shutdown();
 | 
			
		||||
    }
 | 
			
		||||
    void *ProtectFunction(void *function, int num_params);
 | 
			
		||||
private:
 | 
			
		||||
	void Init();
 | 
			
		||||
	void Shutdown();
 | 
			
		||||
	void Reset();
 | 
			
		||||
    void Init();
 | 
			
		||||
    void Shutdown();
 | 
			
		||||
    void Reset();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _THUNK_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -22,11 +22,11 @@ namespace Common
 | 
			
		||||
u32 Timer::GetTimeMs()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	return timeGetTime();
 | 
			
		||||
    return timeGetTime();
 | 
			
		||||
#else
 | 
			
		||||
	struct timeval t;
 | 
			
		||||
	(void)gettimeofday(&t, NULL);
 | 
			
		||||
	return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000));
 | 
			
		||||
    struct timeval t;
 | 
			
		||||
    (void)gettimeofday(&t, NULL);
 | 
			
		||||
    return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -36,31 +36,31 @@ u32 Timer::GetTimeMs()
 | 
			
		||||
 | 
			
		||||
// Set initial values for the class
 | 
			
		||||
Timer::Timer()
 | 
			
		||||
	: m_LastTime(0), m_StartTime(0), m_Running(false)
 | 
			
		||||
    : m_LastTime(0), m_StartTime(0), m_Running(false)
 | 
			
		||||
{
 | 
			
		||||
	Update();
 | 
			
		||||
    Update();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write the starting time
 | 
			
		||||
void Timer::Start()
 | 
			
		||||
{
 | 
			
		||||
	m_StartTime = GetTimeMs();
 | 
			
		||||
	m_Running = true;
 | 
			
		||||
    m_StartTime = GetTimeMs();
 | 
			
		||||
    m_Running = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stop the timer
 | 
			
		||||
void Timer::Stop()
 | 
			
		||||
{
 | 
			
		||||
	// Write the final time
 | 
			
		||||
	m_LastTime = GetTimeMs();
 | 
			
		||||
	m_Running = false;
 | 
			
		||||
    // Write the final time
 | 
			
		||||
    m_LastTime = GetTimeMs();
 | 
			
		||||
    m_Running = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update the last time variable
 | 
			
		||||
void Timer::Update()
 | 
			
		||||
{
 | 
			
		||||
	m_LastTime = GetTimeMs();
 | 
			
		||||
	//TODO(ector) - QPF
 | 
			
		||||
    m_LastTime = GetTimeMs();
 | 
			
		||||
    //TODO(ector) - QPF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// -------------------------------------
 | 
			
		||||
@@ -70,125 +70,125 @@ void Timer::Update()
 | 
			
		||||
// Get the number of milliseconds since the last Update()
 | 
			
		||||
u64 Timer::GetTimeDifference()
 | 
			
		||||
{
 | 
			
		||||
	return GetTimeMs() - m_LastTime;
 | 
			
		||||
    return GetTimeMs() - m_LastTime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add the time difference since the last Update() to the starting time.
 | 
			
		||||
// This is used to compensate for a paused game.
 | 
			
		||||
void Timer::AddTimeDifference()
 | 
			
		||||
{
 | 
			
		||||
	m_StartTime += GetTimeDifference();
 | 
			
		||||
    m_StartTime += GetTimeDifference();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get the time elapsed since the Start()
 | 
			
		||||
u64 Timer::GetTimeElapsed()
 | 
			
		||||
{
 | 
			
		||||
	// If we have not started yet, return 1 (because then I don't
 | 
			
		||||
	// have to change the FPS calculation in CoreRerecording.cpp .
 | 
			
		||||
	if (m_StartTime == 0) return 1;
 | 
			
		||||
    // If we have not started yet, return 1 (because then I don't
 | 
			
		||||
    // have to change the FPS calculation in CoreRerecording.cpp .
 | 
			
		||||
    if (m_StartTime == 0) return 1;
 | 
			
		||||
 | 
			
		||||
	// Return the final timer time if the timer is stopped
 | 
			
		||||
	if (!m_Running) return (m_LastTime - m_StartTime);
 | 
			
		||||
    // Return the final timer time if the timer is stopped
 | 
			
		||||
    if (!m_Running) return (m_LastTime - m_StartTime);
 | 
			
		||||
 | 
			
		||||
	return (GetTimeMs() - m_StartTime);
 | 
			
		||||
    return (GetTimeMs() - m_StartTime);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get the formatted time elapsed since the Start()
 | 
			
		||||
std::string Timer::GetTimeElapsedFormatted() const
 | 
			
		||||
{
 | 
			
		||||
	// If we have not started yet, return zero
 | 
			
		||||
	if (m_StartTime == 0)
 | 
			
		||||
		return "00:00:00:000";
 | 
			
		||||
    // If we have not started yet, return zero
 | 
			
		||||
    if (m_StartTime == 0)
 | 
			
		||||
        return "00:00:00:000";
 | 
			
		||||
 | 
			
		||||
	// The number of milliseconds since the start.
 | 
			
		||||
	// Use a different value if the timer is stopped.
 | 
			
		||||
	u64 Milliseconds;
 | 
			
		||||
	if (m_Running)
 | 
			
		||||
		Milliseconds = GetTimeMs() - m_StartTime;
 | 
			
		||||
	else
 | 
			
		||||
		Milliseconds = m_LastTime - m_StartTime;
 | 
			
		||||
	// Seconds
 | 
			
		||||
	u32 Seconds = (u32)(Milliseconds / 1000);
 | 
			
		||||
	// Minutes
 | 
			
		||||
	u32 Minutes = Seconds / 60;
 | 
			
		||||
	// Hours
 | 
			
		||||
	u32 Hours = Minutes / 60;
 | 
			
		||||
    // The number of milliseconds since the start.
 | 
			
		||||
    // Use a different value if the timer is stopped.
 | 
			
		||||
    u64 Milliseconds;
 | 
			
		||||
    if (m_Running)
 | 
			
		||||
        Milliseconds = GetTimeMs() - m_StartTime;
 | 
			
		||||
    else
 | 
			
		||||
        Milliseconds = m_LastTime - m_StartTime;
 | 
			
		||||
    // Seconds
 | 
			
		||||
    u32 Seconds = (u32)(Milliseconds / 1000);
 | 
			
		||||
    // Minutes
 | 
			
		||||
    u32 Minutes = Seconds / 60;
 | 
			
		||||
    // Hours
 | 
			
		||||
    u32 Hours = Minutes / 60;
 | 
			
		||||
 | 
			
		||||
	std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i",
 | 
			
		||||
		Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000);
 | 
			
		||||
	return TmpStr;
 | 
			
		||||
    std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i",
 | 
			
		||||
        Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000);
 | 
			
		||||
    return TmpStr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get current time
 | 
			
		||||
void Timer::IncreaseResolution()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	timeBeginPeriod(1);
 | 
			
		||||
    timeBeginPeriod(1);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Timer::RestoreResolution()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	timeEndPeriod(1);
 | 
			
		||||
    timeEndPeriod(1);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get the number of seconds since January 1 1970
 | 
			
		||||
u64 Timer::GetTimeSinceJan1970()
 | 
			
		||||
{
 | 
			
		||||
	time_t ltime;
 | 
			
		||||
	time(<ime);
 | 
			
		||||
	return((u64)ltime);
 | 
			
		||||
    time_t ltime;
 | 
			
		||||
    time(<ime);
 | 
			
		||||
    return((u64)ltime);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u64 Timer::GetLocalTimeSinceJan1970()
 | 
			
		||||
{
 | 
			
		||||
	time_t sysTime, tzDiff, tzDST;
 | 
			
		||||
	struct tm * gmTime;
 | 
			
		||||
    time_t sysTime, tzDiff, tzDST;
 | 
			
		||||
    struct tm * gmTime;
 | 
			
		||||
 | 
			
		||||
	time(&sysTime);
 | 
			
		||||
    time(&sysTime);
 | 
			
		||||
 | 
			
		||||
	// Account for DST where needed
 | 
			
		||||
	gmTime = localtime(&sysTime);
 | 
			
		||||
	if(gmTime->tm_isdst == 1)
 | 
			
		||||
		tzDST = 3600;
 | 
			
		||||
	else
 | 
			
		||||
		tzDST = 0;
 | 
			
		||||
    // Account for DST where needed
 | 
			
		||||
    gmTime = localtime(&sysTime);
 | 
			
		||||
    if(gmTime->tm_isdst == 1)
 | 
			
		||||
        tzDST = 3600;
 | 
			
		||||
    else
 | 
			
		||||
        tzDST = 0;
 | 
			
		||||
 | 
			
		||||
	// Lazy way to get local time in sec
 | 
			
		||||
	gmTime	= gmtime(&sysTime);
 | 
			
		||||
	tzDiff = sysTime - mktime(gmTime);
 | 
			
		||||
    // Lazy way to get local time in sec
 | 
			
		||||
    gmTime    = gmtime(&sysTime);
 | 
			
		||||
    tzDiff = sysTime - mktime(gmTime);
 | 
			
		||||
 | 
			
		||||
	return (u64)(sysTime + tzDiff + tzDST);
 | 
			
		||||
    return (u64)(sysTime + tzDiff + tzDST);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Return the current time formatted as Minutes:Seconds:Milliseconds
 | 
			
		||||
// in the form 00:00:000.
 | 
			
		||||
std::string Timer::GetTimeFormatted()
 | 
			
		||||
{
 | 
			
		||||
	time_t sysTime;
 | 
			
		||||
	struct tm * gmTime;
 | 
			
		||||
	char formattedTime[13];
 | 
			
		||||
	char tmp[13];
 | 
			
		||||
    time_t sysTime;
 | 
			
		||||
    struct tm * gmTime;
 | 
			
		||||
    char formattedTime[13];
 | 
			
		||||
    char tmp[13];
 | 
			
		||||
 | 
			
		||||
	time(&sysTime);
 | 
			
		||||
	gmTime = localtime(&sysTime);
 | 
			
		||||
    time(&sysTime);
 | 
			
		||||
    gmTime = localtime(&sysTime);
 | 
			
		||||
 | 
			
		||||
	strftime(tmp, 6, "%M:%S", gmTime);
 | 
			
		||||
    strftime(tmp, 6, "%M:%S", gmTime);
 | 
			
		||||
 | 
			
		||||
	// Now tack on the milliseconds
 | 
			
		||||
    // Now tack on the milliseconds
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	struct timeb tp;
 | 
			
		||||
	(void)::ftime(&tp);
 | 
			
		||||
	sprintf(formattedTime, "%s:%03i", tmp, tp.millitm);
 | 
			
		||||
    struct timeb tp;
 | 
			
		||||
    (void)::ftime(&tp);
 | 
			
		||||
    sprintf(formattedTime, "%s:%03i", tmp, tp.millitm);
 | 
			
		||||
#else
 | 
			
		||||
	struct timeval t;
 | 
			
		||||
	(void)gettimeofday(&t, NULL);
 | 
			
		||||
	sprintf(formattedTime, "%s:%03d", tmp, (int)(t.tv_usec / 1000));
 | 
			
		||||
    struct timeval t;
 | 
			
		||||
    (void)gettimeofday(&t, NULL);
 | 
			
		||||
    sprintf(formattedTime, "%s:%03d", tmp, (int)(t.tv_usec / 1000));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return std::string(formattedTime);
 | 
			
		||||
    return std::string(formattedTime);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns a timestamp with decimals for precise time comparisons
 | 
			
		||||
@@ -196,31 +196,31 @@ std::string Timer::GetTimeFormatted()
 | 
			
		||||
double Timer::GetDoubleTime()
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	struct timeb tp;
 | 
			
		||||
	(void)::ftime(&tp);
 | 
			
		||||
    struct timeb tp;
 | 
			
		||||
    (void)::ftime(&tp);
 | 
			
		||||
#else
 | 
			
		||||
	struct timeval t;
 | 
			
		||||
	(void)gettimeofday(&t, NULL);
 | 
			
		||||
    struct timeval t;
 | 
			
		||||
    (void)gettimeofday(&t, NULL);
 | 
			
		||||
#endif
 | 
			
		||||
	// Get continuous timestamp
 | 
			
		||||
	u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970();
 | 
			
		||||
    // Get continuous timestamp
 | 
			
		||||
    u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970();
 | 
			
		||||
 | 
			
		||||
	// Remove a few years. We only really want enough seconds to make
 | 
			
		||||
	// sure that we are detecting actual actions, perhaps 60 seconds is
 | 
			
		||||
	// enough really, but I leave a year of seconds anyway, in case the
 | 
			
		||||
	// user's clock is incorrect or something like that.
 | 
			
		||||
	TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60);
 | 
			
		||||
    // Remove a few years. We only really want enough seconds to make
 | 
			
		||||
    // sure that we are detecting actual actions, perhaps 60 seconds is
 | 
			
		||||
    // enough really, but I leave a year of seconds anyway, in case the
 | 
			
		||||
    // user's clock is incorrect or something like that.
 | 
			
		||||
    TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60);
 | 
			
		||||
 | 
			
		||||
	// Make a smaller integer that fits in the double
 | 
			
		||||
	u32 Seconds = (u32)TmpSeconds;
 | 
			
		||||
    // Make a smaller integer that fits in the double
 | 
			
		||||
    u32 Seconds = (u32)TmpSeconds;
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	double ms = tp.millitm / 1000.0 / 1000.0;
 | 
			
		||||
    double ms = tp.millitm / 1000.0 / 1000.0;
 | 
			
		||||
#else
 | 
			
		||||
	double ms = t.tv_usec / 1000000.0;
 | 
			
		||||
    double ms = t.tv_usec / 1000000.0;
 | 
			
		||||
#endif
 | 
			
		||||
	double TmpTime = Seconds + ms;
 | 
			
		||||
    double TmpTime = Seconds + ms;
 | 
			
		||||
 | 
			
		||||
	return TmpTime;
 | 
			
		||||
    return TmpTime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // Namespace Common
 | 
			
		||||
 
 | 
			
		||||
@@ -13,32 +13,32 @@ namespace Common
 | 
			
		||||
class Timer
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	Timer();
 | 
			
		||||
    Timer();
 | 
			
		||||
 | 
			
		||||
	void Start();
 | 
			
		||||
	void Stop();
 | 
			
		||||
	void Update();
 | 
			
		||||
    void Start();
 | 
			
		||||
    void Stop();
 | 
			
		||||
    void Update();
 | 
			
		||||
 | 
			
		||||
	// The time difference is always returned in milliseconds, regardless of alternative internal representation
 | 
			
		||||
	u64 GetTimeDifference();
 | 
			
		||||
	void AddTimeDifference();
 | 
			
		||||
    // The time difference is always returned in milliseconds, regardless of alternative internal representation
 | 
			
		||||
    u64 GetTimeDifference();
 | 
			
		||||
    void AddTimeDifference();
 | 
			
		||||
 | 
			
		||||
	static void IncreaseResolution();
 | 
			
		||||
	static void RestoreResolution();
 | 
			
		||||
	static u64 GetTimeSinceJan1970();
 | 
			
		||||
	static u64 GetLocalTimeSinceJan1970();
 | 
			
		||||
	static double GetDoubleTime();
 | 
			
		||||
    static void IncreaseResolution();
 | 
			
		||||
    static void RestoreResolution();
 | 
			
		||||
    static u64 GetTimeSinceJan1970();
 | 
			
		||||
    static u64 GetLocalTimeSinceJan1970();
 | 
			
		||||
    static double GetDoubleTime();
 | 
			
		||||
 | 
			
		||||
	static std::string GetTimeFormatted();
 | 
			
		||||
	std::string GetTimeElapsedFormatted() const;
 | 
			
		||||
	u64 GetTimeElapsed();
 | 
			
		||||
    static std::string GetTimeFormatted();
 | 
			
		||||
    std::string GetTimeElapsedFormatted() const;
 | 
			
		||||
    u64 GetTimeElapsed();
 | 
			
		||||
 | 
			
		||||
	static u32 GetTimeMs();
 | 
			
		||||
    static u32 GetTimeMs();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	u64 m_LastTime;
 | 
			
		||||
	u64 m_StartTime;
 | 
			
		||||
	bool m_Running;
 | 
			
		||||
    u64 m_LastTime;
 | 
			
		||||
    u64 m_StartTime;
 | 
			
		||||
    bool m_Running;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // Namespace Common
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
 | 
			
		||||
// is start of UTF sequence
 | 
			
		||||
inline bool isutf(char c) {
 | 
			
		||||
	return (c & 0xC0) != 0x80;
 | 
			
		||||
    return (c & 0xC0) != 0x80;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const u32 offsetsFromUTF8[6] = {
 | 
			
		||||
@@ -47,7 +47,7 @@ static const u8 trailingBytesForUTF8[256] = {
 | 
			
		||||
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 | 
			
		||||
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 | 
			
		||||
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 | 
			
		||||
		2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,
 | 
			
		||||
        2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* returns length of next utf-8 sequence */
 | 
			
		||||
@@ -405,59 +405,59 @@ int u8_is_locale_utf8(const char *locale)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int UTF8StringNonASCIICount(const char *utf8string) {
 | 
			
		||||
	UTF8 utf(utf8string);
 | 
			
		||||
	int count = 0;
 | 
			
		||||
	while (!utf.end()) {
 | 
			
		||||
		int c = utf.next();
 | 
			
		||||
		if (c > 127)
 | 
			
		||||
			++count;
 | 
			
		||||
	}
 | 
			
		||||
	return count;
 | 
			
		||||
    UTF8 utf(utf8string);
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    while (!utf.end()) {
 | 
			
		||||
        int c = utf.next();
 | 
			
		||||
        if (c > 127)
 | 
			
		||||
            ++count;
 | 
			
		||||
    }
 | 
			
		||||
    return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool UTF8StringHasNonASCII(const char *utf8string) {
 | 
			
		||||
	return UTF8StringNonASCIICount(utf8string) > 0;
 | 
			
		||||
    return UTF8StringNonASCIICount(utf8string) > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
 | 
			
		||||
std::string ConvertWStringToUTF8(const wchar_t *wstr) {
 | 
			
		||||
	int len = (int)wcslen(wstr);
 | 
			
		||||
	int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, NULL, NULL);
 | 
			
		||||
	std::string s;
 | 
			
		||||
	s.resize(size);
 | 
			
		||||
	if (size > 0) {
 | 
			
		||||
		WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, NULL, NULL);
 | 
			
		||||
	}
 | 
			
		||||
	return s;
 | 
			
		||||
    int len = (int)wcslen(wstr);
 | 
			
		||||
    int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, NULL, NULL);
 | 
			
		||||
    std::string s;
 | 
			
		||||
    s.resize(size);
 | 
			
		||||
    if (size > 0) {
 | 
			
		||||
        WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, NULL, NULL);
 | 
			
		||||
    }
 | 
			
		||||
    return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ConvertWStringToUTF8(const std::wstring &wstr) {
 | 
			
		||||
	int len = (int)wstr.size();
 | 
			
		||||
	int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL);
 | 
			
		||||
	std::string s;
 | 
			
		||||
	s.resize(size);
 | 
			
		||||
	if (size > 0) {
 | 
			
		||||
		WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, NULL, NULL);
 | 
			
		||||
	}
 | 
			
		||||
	return s;
 | 
			
		||||
    int len = (int)wstr.size();
 | 
			
		||||
    int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL);
 | 
			
		||||
    std::string s;
 | 
			
		||||
    s.resize(size);
 | 
			
		||||
    if (size > 0) {
 | 
			
		||||
        WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, NULL, NULL);
 | 
			
		||||
    }
 | 
			
		||||
    return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) {
 | 
			
		||||
	int len = (int)source.size();
 | 
			
		||||
	int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0);
 | 
			
		||||
	MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size));
 | 
			
		||||
    int len = (int)source.size();
 | 
			
		||||
    int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0);
 | 
			
		||||
    MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::wstring ConvertUTF8ToWString(const std::string &source) {
 | 
			
		||||
	int len = (int)source.size();
 | 
			
		||||
	int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0);
 | 
			
		||||
	std::wstring str;
 | 
			
		||||
	str.resize(size);
 | 
			
		||||
	if (size > 0) {
 | 
			
		||||
		MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, &str[0], size);
 | 
			
		||||
	}
 | 
			
		||||
	return str;
 | 
			
		||||
    int len = (int)source.size();
 | 
			
		||||
    int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0);
 | 
			
		||||
    std::wstring str;
 | 
			
		||||
    str.resize(size);
 | 
			
		||||
    if (size > 0) {
 | 
			
		||||
        MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, &str[0], size);
 | 
			
		||||
    }
 | 
			
		||||
    return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -25,29 +25,29 @@ int u8_strlen(const char *s);
 | 
			
		||||
 | 
			
		||||
class UTF8 {
 | 
			
		||||
public:
 | 
			
		||||
	static const u32 INVALID = (u32)-1;
 | 
			
		||||
	UTF8(const char *c) : c_(c), index_(0) {}
 | 
			
		||||
	bool end() const { return c_[index_] == 0; }
 | 
			
		||||
	u32 next() {
 | 
			
		||||
		return u8_nextchar(c_, &index_);
 | 
			
		||||
	}
 | 
			
		||||
	u32 peek() {
 | 
			
		||||
		int tempIndex = index_;
 | 
			
		||||
		return u8_nextchar(c_, &tempIndex);
 | 
			
		||||
	}
 | 
			
		||||
	int length() const {
 | 
			
		||||
		return u8_strlen(c_);
 | 
			
		||||
	}
 | 
			
		||||
	int byteIndex() const {
 | 
			
		||||
		return index_;
 | 
			
		||||
	}
 | 
			
		||||
	static int encode(char *dest, u32 ch) {
 | 
			
		||||
		return u8_wc_toutf8(dest, ch);
 | 
			
		||||
	}
 | 
			
		||||
    static const u32 INVALID = (u32)-1;
 | 
			
		||||
    UTF8(const char *c) : c_(c), index_(0) {}
 | 
			
		||||
    bool end() const { return c_[index_] == 0; }
 | 
			
		||||
    u32 next() {
 | 
			
		||||
        return u8_nextchar(c_, &index_);
 | 
			
		||||
    }
 | 
			
		||||
    u32 peek() {
 | 
			
		||||
        int tempIndex = index_;
 | 
			
		||||
        return u8_nextchar(c_, &tempIndex);
 | 
			
		||||
    }
 | 
			
		||||
    int length() const {
 | 
			
		||||
        return u8_strlen(c_);
 | 
			
		||||
    }
 | 
			
		||||
    int byteIndex() const {
 | 
			
		||||
        return index_;
 | 
			
		||||
    }
 | 
			
		||||
    static int encode(char *dest, u32 ch) {
 | 
			
		||||
        return u8_wc_toutf8(dest, ch);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	const char *c_;
 | 
			
		||||
	int index_;
 | 
			
		||||
    const char *c_;
 | 
			
		||||
    int index_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int UTF8StringNonASCIICount(const char *utf8string);
 | 
			
		||||
 
 | 
			
		||||
@@ -6,22 +6,22 @@
 | 
			
		||||
#include "scm_rev.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _DEBUG
 | 
			
		||||
	#define BUILD_TYPE_STR "Debug "
 | 
			
		||||
    #define BUILD_TYPE_STR "Debug "
 | 
			
		||||
#elif defined DEBUGFAST
 | 
			
		||||
	#define BUILD_TYPE_STR "DebugFast "
 | 
			
		||||
    #define BUILD_TYPE_STR "DebugFast "
 | 
			
		||||
#else
 | 
			
		||||
	#define BUILD_TYPE_STR ""
 | 
			
		||||
    #define BUILD_TYPE_STR ""
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
const char *scm_rev_str = "emu "
 | 
			
		||||
#if !SCM_IS_MASTER
 | 
			
		||||
	"[" SCM_BRANCH_STR "] "
 | 
			
		||||
    "[" SCM_BRANCH_STR "] "
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __INTEL_COMPILER
 | 
			
		||||
	BUILD_TYPE_STR SCM_DESC_STR "-ICC";
 | 
			
		||||
    BUILD_TYPE_STR SCM_DESC_STR "-ICC";
 | 
			
		||||
#else
 | 
			
		||||
	BUILD_TYPE_STR SCM_DESC_STR;
 | 
			
		||||
    BUILD_TYPE_STR SCM_DESC_STR;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _M_X64
 | 
			
		||||
@@ -29,7 +29,7 @@ const char *scm_rev_str = "emu "
 | 
			
		||||
#else
 | 
			
		||||
#ifdef _M_ARM
 | 
			
		||||
#define NP_ARCH "ARM"
 | 
			
		||||
#else	
 | 
			
		||||
#else    
 | 
			
		||||
#define NP_ARCH "x86"
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user