diff options
| author | 2014-04-01 18:20:08 -0400 | |
|---|---|---|
| committer | 2014-04-01 18:48:08 -0400 | |
| commit | c9b5b89e21ba9ea844bfd5407bfe42f35076a35e (patch) | |
| tree | 9ed57547ae2330aec9296b484393fa70e057c5b6 /src/common | |
| parent | convert tabs to spaces (diff) | |
| download | yuzu-c9b5b89e21ba9ea844bfd5407bfe42f35076a35e.tar.gz yuzu-c9b5b89e21ba9ea844bfd5407bfe42f35076a35e.tar.xz yuzu-c9b5b89e21ba9ea844bfd5407bfe42f35076a35e.zip | |
convert tabs to spaces
Diffstat (limited to 'src/common')
47 files changed, 5298 insertions, 5298 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 0e0a43464..c4f060db0 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -1,18 +1,18 @@ | |||
| 1 | set(SRCS src/break_points.cpp | 1 | set(SRCS src/break_points.cpp |
| 2 | src/console_listener.cpp | 2 | src/console_listener.cpp |
| 3 | src/extended_trace.cpp | 3 | src/extended_trace.cpp |
| 4 | src/file_search.cpp | 4 | src/file_search.cpp |
| 5 | src/file_util.cpp | 5 | src/file_util.cpp |
| 6 | src/hash.cpp | 6 | src/hash.cpp |
| 7 | src/log_manager.cpp | 7 | src/log_manager.cpp |
| 8 | src/math_util.cpp | 8 | src/math_util.cpp |
| 9 | src/mem_arena.cpp | 9 | src/mem_arena.cpp |
| 10 | src/memory_util.cpp | 10 | src/memory_util.cpp |
| 11 | src/misc.cpp | 11 | src/misc.cpp |
| 12 | src/msg_handler.cpp | 12 | src/msg_handler.cpp |
| 13 | src/string_util.cpp | 13 | src/string_util.cpp |
| 14 | src/thread.cpp | 14 | src/thread.cpp |
| 15 | src/timer.cpp | 15 | src/timer.cpp |
| 16 | src/version.cpp) | 16 | src/version.cpp) |
| 17 | 17 | ||
| 18 | add_library(common STATIC ${SRCS}) | 18 | add_library(common STATIC ${SRCS}) |
diff --git a/src/common/src/atomic_gcc.h b/src/common/src/atomic_gcc.h index 0f820f4fa..2eb38697b 100644 --- a/src/common/src/atomic_gcc.h +++ b/src/common/src/atomic_gcc.h | |||
| @@ -25,42 +25,42 @@ namespace Common | |||
| 25 | { | 25 | { |
| 26 | 26 | ||
| 27 | inline void AtomicAdd(volatile u32& target, u32 value) { | 27 | inline void AtomicAdd(volatile u32& target, u32 value) { |
| 28 | __sync_add_and_fetch(&target, value); | 28 | __sync_add_and_fetch(&target, value); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | inline void AtomicAnd(volatile u32& target, u32 value) { | 31 | inline void AtomicAnd(volatile u32& target, u32 value) { |
| 32 | __sync_and_and_fetch(&target, value); | 32 | __sync_and_and_fetch(&target, value); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | inline void AtomicDecrement(volatile u32& target) { | 35 | inline void AtomicDecrement(volatile u32& target) { |
| 36 | __sync_add_and_fetch(&target, -1); | 36 | __sync_add_and_fetch(&target, -1); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | inline void AtomicIncrement(volatile u32& target) { | 39 | inline void AtomicIncrement(volatile u32& target) { |
| 40 | __sync_add_and_fetch(&target, 1); | 40 | __sync_add_and_fetch(&target, 1); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | inline u32 AtomicLoad(volatile u32& src) { | 43 | inline u32 AtomicLoad(volatile u32& src) { |
| 44 | return src; // 32-bit reads are always atomic. | 44 | return src; // 32-bit reads are always atomic. |
| 45 | } | 45 | } |
| 46 | inline u32 AtomicLoadAcquire(volatile u32& src) { | 46 | inline u32 AtomicLoadAcquire(volatile u32& src) { |
| 47 | //keep the compiler from caching any memory references | 47 | //keep the compiler from caching any memory references |
| 48 | u32 result = src; // 32-bit reads are always atomic. | 48 | u32 result = src; // 32-bit reads are always atomic. |
| 49 | //__sync_synchronize(); // TODO: May not be necessary. | 49 | //__sync_synchronize(); // TODO: May not be necessary. |
| 50 | // Compiler instruction only. x86 loads always have acquire semantics. | 50 | // Compiler instruction only. x86 loads always have acquire semantics. |
| 51 | __asm__ __volatile__ ( "":::"memory" ); | 51 | __asm__ __volatile__ ( "":::"memory" ); |
| 52 | return result; | 52 | return result; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | inline void AtomicOr(volatile u32& target, u32 value) { | 55 | inline void AtomicOr(volatile u32& target, u32 value) { |
| 56 | __sync_or_and_fetch(&target, value); | 56 | __sync_or_and_fetch(&target, value); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | inline void AtomicStore(volatile u32& dest, u32 value) { | 59 | inline void AtomicStore(volatile u32& dest, u32 value) { |
| 60 | dest = value; // 32-bit writes are always atomic. | 60 | dest = value; // 32-bit writes are always atomic. |
| 61 | } | 61 | } |
| 62 | inline void AtomicStoreRelease(volatile u32& dest, u32 value) { | 62 | inline void AtomicStoreRelease(volatile u32& dest, u32 value) { |
| 63 | __sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics. | 63 | __sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics. |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | } | 66 | } |
diff --git a/src/common/src/atomic_win32.h b/src/common/src/atomic_win32.h index 31ee0b784..760b16d4d 100644 --- a/src/common/src/atomic_win32.h +++ b/src/common/src/atomic_win32.h | |||
| @@ -31,40 +31,40 @@ namespace Common | |||
| 31 | { | 31 | { |
| 32 | 32 | ||
| 33 | inline void AtomicAdd(volatile u32& target, u32 value) { | 33 | inline void AtomicAdd(volatile u32& target, u32 value) { |
| 34 | InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value); | 34 | InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | inline void AtomicAnd(volatile u32& target, u32 value) { | 37 | inline void AtomicAnd(volatile u32& target, u32 value) { |
| 38 | _InterlockedAnd((volatile LONG*)&target, (LONG)value); | 38 | _InterlockedAnd((volatile LONG*)&target, (LONG)value); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | inline void AtomicIncrement(volatile u32& target) { | 41 | inline void AtomicIncrement(volatile u32& target) { |
| 42 | InterlockedIncrement((volatile LONG*)&target); | 42 | InterlockedIncrement((volatile LONG*)&target); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | inline void AtomicDecrement(volatile u32& target) { | 45 | inline void AtomicDecrement(volatile u32& target) { |
| 46 | InterlockedDecrement((volatile LONG*)&target); | 46 | InterlockedDecrement((volatile LONG*)&target); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | inline u32 AtomicLoad(volatile u32& src) { | 49 | inline u32 AtomicLoad(volatile u32& src) { |
| 50 | return src; // 32-bit reads are always atomic. | 50 | return src; // 32-bit reads are always atomic. |
| 51 | } | 51 | } |
| 52 | inline u32 AtomicLoadAcquire(volatile u32& src) { | 52 | inline u32 AtomicLoadAcquire(volatile u32& src) { |
| 53 | u32 result = src; // 32-bit reads are always atomic. | 53 | u32 result = src; // 32-bit reads are always atomic. |
| 54 | _ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics. | 54 | _ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics. |
| 55 | return result; | 55 | return result; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | inline void AtomicOr(volatile u32& target, u32 value) { | 58 | inline void AtomicOr(volatile u32& target, u32 value) { |
| 59 | _InterlockedOr((volatile LONG*)&target, (LONG)value); | 59 | _InterlockedOr((volatile LONG*)&target, (LONG)value); |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | inline void AtomicStore(volatile u32& dest, u32 value) { | 62 | inline void AtomicStore(volatile u32& dest, u32 value) { |
| 63 | dest = value; // 32-bit writes are always atomic. | 63 | dest = value; // 32-bit writes are always atomic. |
| 64 | } | 64 | } |
| 65 | inline void AtomicStoreRelease(volatile u32& dest, u32 value) { | 65 | inline void AtomicStoreRelease(volatile u32& dest, u32 value) { |
| 66 | _WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics. | 66 | _WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics. |
| 67 | dest = value; // 32-bit writes are always atomic. | 67 | dest = value; // 32-bit writes are always atomic. |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | } | 70 | } |
diff --git a/src/common/src/break_points.cpp b/src/common/src/break_points.cpp index 9e5c65153..787263f79 100644 --- a/src/common/src/break_points.cpp +++ b/src/common/src/break_points.cpp | |||
| @@ -11,193 +11,193 @@ | |||
| 11 | 11 | ||
| 12 | bool BreakPoints::IsAddressBreakPoint(u32 _iAddress) | 12 | bool BreakPoints::IsAddressBreakPoint(u32 _iAddress) |
| 13 | { | 13 | { |
| 14 | for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | 14 | for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) |
| 15 | if (i->iAddress == _iAddress) | 15 | if (i->iAddress == _iAddress) |
| 16 | return true; | 16 | return true; |
| 17 | return false; | 17 | return false; |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | bool BreakPoints::IsTempBreakPoint(u32 _iAddress) | 20 | bool BreakPoints::IsTempBreakPoint(u32 _iAddress) |
| 21 | { | 21 | { |
| 22 | for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | 22 | for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) |
| 23 | if (i->iAddress == _iAddress && i->bTemporary) | 23 | if (i->iAddress == _iAddress && i->bTemporary) |
| 24 | return true; | 24 | return true; |
| 25 | return false; | 25 | return false; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const | 28 | BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const |
| 29 | { | 29 | { |
| 30 | TBreakPointsStr bps; | 30 | TBreakPointsStr bps; |
| 31 | for (TBreakPoints::const_iterator i = m_BreakPoints.begin(); | 31 | for (TBreakPoints::const_iterator i = m_BreakPoints.begin(); |
| 32 | i != m_BreakPoints.end(); ++i) | 32 | i != m_BreakPoints.end(); ++i) |
| 33 | { | 33 | { |
| 34 | if (!i->bTemporary) | 34 | if (!i->bTemporary) |
| 35 | { | 35 | { |
| 36 | std::stringstream bp; | 36 | std::stringstream bp; |
| 37 | bp << std::hex << i->iAddress << " " << (i->bOn ? "n" : ""); | 37 | bp << std::hex << i->iAddress << " " << (i->bOn ? "n" : ""); |
| 38 | bps.push_back(bp.str()); | 38 | bps.push_back(bp.str()); |
| 39 | } | 39 | } |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | return bps; | 42 | return bps; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) | 45 | void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) |
| 46 | { | 46 | { |
| 47 | for (TBreakPointsStr::const_iterator i = bps.begin(); i != bps.end(); ++i) | 47 | for (TBreakPointsStr::const_iterator i = bps.begin(); i != bps.end(); ++i) |
| 48 | { | 48 | { |
| 49 | TBreakPoint bp; | 49 | TBreakPoint bp; |
| 50 | std::stringstream bpstr; | 50 | std::stringstream bpstr; |
| 51 | bpstr << std::hex << *i; | 51 | bpstr << std::hex << *i; |
| 52 | bpstr >> bp.iAddress; | 52 | bpstr >> bp.iAddress; |
| 53 | bp.bOn = i->find("n") != i->npos; | 53 | bp.bOn = i->find("n") != i->npos; |
| 54 | bp.bTemporary = false; | 54 | bp.bTemporary = false; |
| 55 | Add(bp); | 55 | Add(bp); |
| 56 | } | 56 | } |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | void BreakPoints::Add(const TBreakPoint& bp) | 59 | void BreakPoints::Add(const TBreakPoint& bp) |
| 60 | { | 60 | { |
| 61 | if (!IsAddressBreakPoint(bp.iAddress)) | 61 | if (!IsAddressBreakPoint(bp.iAddress)) |
| 62 | { | 62 | { |
| 63 | m_BreakPoints.push_back(bp); | 63 | m_BreakPoints.push_back(bp); |
| 64 | //if (jit) | 64 | //if (jit) |
| 65 | // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4); | 65 | // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4); |
| 66 | } | 66 | } |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | void BreakPoints::Add(u32 em_address, bool temp) | 69 | void BreakPoints::Add(u32 em_address, bool temp) |
| 70 | { | 70 | { |
| 71 | if (!IsAddressBreakPoint(em_address)) // only add new addresses | 71 | if (!IsAddressBreakPoint(em_address)) // only add new addresses |
| 72 | { | 72 | { |
| 73 | TBreakPoint pt; // breakpoint settings | 73 | TBreakPoint pt; // breakpoint settings |
| 74 | pt.bOn = true; | 74 | pt.bOn = true; |
| 75 | pt.bTemporary = temp; | 75 | pt.bTemporary = temp; |
| 76 | pt.iAddress = em_address; | 76 | pt.iAddress = em_address; |
| 77 | 77 | ||
| 78 | m_BreakPoints.push_back(pt); | 78 | m_BreakPoints.push_back(pt); |
| 79 | 79 | ||
| 80 | //if (jit) | 80 | //if (jit) |
| 81 | // jit->GetBlockCache()->InvalidateICache(em_address, 4); | 81 | // jit->GetBlockCache()->InvalidateICache(em_address, 4); |
| 82 | } | 82 | } |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | void BreakPoints::Remove(u32 em_address) | 85 | void BreakPoints::Remove(u32 em_address) |
| 86 | { | 86 | { |
| 87 | for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) | 87 | for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) |
| 88 | { | 88 | { |
| 89 | if (i->iAddress == em_address) | 89 | if (i->iAddress == em_address) |
| 90 | { | 90 | { |
| 91 | m_BreakPoints.erase(i); | 91 | m_BreakPoints.erase(i); |
| 92 | //if (jit) | 92 | //if (jit) |
| 93 | // jit->GetBlockCache()->InvalidateICache(em_address, 4); | 93 | // jit->GetBlockCache()->InvalidateICache(em_address, 4); |
| 94 | return; | 94 | return; |
| 95 | } | 95 | } |
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | void BreakPoints::Clear() | 99 | void BreakPoints::Clear() |
| 100 | { | 100 | { |
| 101 | //if (jit) | 101 | //if (jit) |
| 102 | //{ | 102 | //{ |
| 103 | // std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(), | 103 | // std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(), |
| 104 | // [](const TBreakPoint& bp) | 104 | // [](const TBreakPoint& bp) |
| 105 | // { | 105 | // { |
| 106 | // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4); | 106 | // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4); |
| 107 | // } | 107 | // } |
| 108 | // ); | 108 | // ); |
| 109 | //} | 109 | //} |
| 110 | 110 | ||
| 111 | m_BreakPoints.clear(); | 111 | m_BreakPoints.clear(); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | MemChecks::TMemChecksStr MemChecks::GetStrings() const | 114 | MemChecks::TMemChecksStr MemChecks::GetStrings() const |
| 115 | { | 115 | { |
| 116 | TMemChecksStr mcs; | 116 | TMemChecksStr mcs; |
| 117 | for (TMemChecks::const_iterator i = m_MemChecks.begin(); | 117 | for (TMemChecks::const_iterator i = m_MemChecks.begin(); |
| 118 | i != m_MemChecks.end(); ++i) | 118 | i != m_MemChecks.end(); ++i) |
| 119 | { | 119 | { |
| 120 | std::stringstream mc; | 120 | std::stringstream mc; |
| 121 | mc << std::hex << i->StartAddress; | 121 | mc << std::hex << i->StartAddress; |
| 122 | mc << " " << (i->bRange ? i->EndAddress : i->StartAddress) << " " << | 122 | mc << " " << (i->bRange ? i->EndAddress : i->StartAddress) << " " << |
| 123 | (i->bRange ? "n" : "") << (i->OnRead ? "r" : "") << | 123 | (i->bRange ? "n" : "") << (i->OnRead ? "r" : "") << |
| 124 | (i->OnWrite ? "w" : "") << (i->Log ? "l" : "") << (i->Break ? "p" : ""); | 124 | (i->OnWrite ? "w" : "") << (i->Log ? "l" : "") << (i->Break ? "p" : ""); |
| 125 | mcs.push_back(mc.str()); | 125 | mcs.push_back(mc.str()); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | return mcs; | 128 | return mcs; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | void MemChecks::AddFromStrings(const TMemChecksStr& mcs) | 131 | void MemChecks::AddFromStrings(const TMemChecksStr& mcs) |
| 132 | { | 132 | { |
| 133 | for (TMemChecksStr::const_iterator i = mcs.begin(); i != mcs.end(); ++i) | 133 | for (TMemChecksStr::const_iterator i = mcs.begin(); i != mcs.end(); ++i) |
| 134 | { | 134 | { |
| 135 | TMemCheck mc; | 135 | TMemCheck mc; |
| 136 | std::stringstream mcstr; | 136 | std::stringstream mcstr; |
| 137 | mcstr << std::hex << *i; | 137 | mcstr << std::hex << *i; |
| 138 | mcstr >> mc.StartAddress; | 138 | mcstr >> mc.StartAddress; |
| 139 | mc.bRange = i->find("n") != i->npos; | 139 | mc.bRange = i->find("n") != i->npos; |
| 140 | mc.OnRead = i->find("r") != i->npos; | 140 | mc.OnRead = i->find("r") != i->npos; |
| 141 | mc.OnWrite = i->find("w") != i->npos; | 141 | mc.OnWrite = i->find("w") != i->npos; |
| 142 | mc.Log = i->find("l") != i->npos; | 142 | mc.Log = i->find("l") != i->npos; |
| 143 | mc.Break = i->find("p") != i->npos; | 143 | mc.Break = i->find("p") != i->npos; |
| 144 | if (mc.bRange) | 144 | if (mc.bRange) |
| 145 | mcstr >> mc.EndAddress; | 145 | mcstr >> mc.EndAddress; |
| 146 | else | 146 | else |
| 147 | mc.EndAddress = mc.StartAddress; | 147 | mc.EndAddress = mc.StartAddress; |
| 148 | Add(mc); | 148 | Add(mc); |
| 149 | } | 149 | } |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | void MemChecks::Add(const TMemCheck& _rMemoryCheck) | 152 | void MemChecks::Add(const TMemCheck& _rMemoryCheck) |
| 153 | { | 153 | { |
| 154 | if (GetMemCheck(_rMemoryCheck.StartAddress) == 0) | 154 | if (GetMemCheck(_rMemoryCheck.StartAddress) == 0) |
| 155 | m_MemChecks.push_back(_rMemoryCheck); | 155 | m_MemChecks.push_back(_rMemoryCheck); |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | void MemChecks::Remove(u32 _Address) | 158 | void MemChecks::Remove(u32 _Address) |
| 159 | { | 159 | { |
| 160 | for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) | 160 | for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) |
| 161 | { | 161 | { |
| 162 | if (i->StartAddress == _Address) | 162 | if (i->StartAddress == _Address) |
| 163 | { | 163 | { |
| 164 | m_MemChecks.erase(i); | 164 | m_MemChecks.erase(i); |
| 165 | return; | 165 | return; |
| 166 | } | 166 | } |
| 167 | } | 167 | } |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | TMemCheck *MemChecks::GetMemCheck(u32 address) | 170 | TMemCheck *MemChecks::GetMemCheck(u32 address) |
| 171 | { | 171 | { |
| 172 | for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) | 172 | for (TMemChecks::iterator i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i) |
| 173 | { | 173 | { |
| 174 | if (i->bRange) | 174 | if (i->bRange) |
| 175 | { | 175 | { |
| 176 | if (address >= i->StartAddress && address <= i->EndAddress) | 176 | if (address >= i->StartAddress && address <= i->EndAddress) |
| 177 | return &(*i); | 177 | return &(*i); |
| 178 | } | 178 | } |
| 179 | else if (i->StartAddress == address) | 179 | else if (i->StartAddress == address) |
| 180 | return &(*i); | 180 | return &(*i); |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | // none found | 183 | // none found |
| 184 | return 0; | 184 | return 0; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | void TMemCheck::Action(DebugInterface *debug_interface, u32 iValue, u32 addr, | 187 | void TMemCheck::Action(DebugInterface *debug_interface, u32 iValue, u32 addr, |
| 188 | bool write, int size, u32 pc) | 188 | bool write, int size, u32 pc) |
| 189 | { | 189 | { |
| 190 | if ((write && OnWrite) || (!write && OnRead)) | 190 | if ((write && OnWrite) || (!write && OnRead)) |
| 191 | { | 191 | { |
| 192 | if (Log) | 192 | if (Log) |
| 193 | { | 193 | { |
| 194 | INFO_LOG(MEMMAP, "CHK %08x (%s) %s%i %0*x at %08x (%s)", | 194 | INFO_LOG(MEMMAP, "CHK %08x (%s) %s%i %0*x at %08x (%s)", |
| 195 | pc, debug_interface->getDescription(pc).c_str(), | 195 | pc, debug_interface->getDescription(pc).c_str(), |
| 196 | write ? "Write" : "Read", size*8, size*2, iValue, addr, | 196 | write ? "Write" : "Read", size*8, size*2, iValue, addr, |
| 197 | debug_interface->getDescription(addr).c_str() | 197 | debug_interface->getDescription(addr).c_str() |
| 198 | ); | 198 | ); |
| 199 | } | 199 | } |
| 200 | if (Break) | 200 | if (Break) |
| 201 | debug_interface->breakNow(); | 201 | debug_interface->breakNow(); |
| 202 | } | 202 | } |
| 203 | } | 203 | } |
diff --git a/src/common/src/break_points.h b/src/common/src/break_points.h index 281de1004..dc771ba01 100644 --- a/src/common/src/break_points.h +++ b/src/common/src/break_points.h | |||
| @@ -14,64 +14,64 @@ class DebugInterface; | |||
| 14 | 14 | ||
| 15 | struct TBreakPoint | 15 | struct TBreakPoint |
| 16 | { | 16 | { |
| 17 | u32 iAddress; | 17 | u32 iAddress; |
| 18 | bool bOn; | 18 | bool bOn; |
| 19 | bool bTemporary; | 19 | bool bTemporary; |
| 20 | }; | 20 | }; |
| 21 | 21 | ||
| 22 | struct TMemCheck | 22 | struct TMemCheck |
| 23 | { | 23 | { |
| 24 | TMemCheck() { | 24 | TMemCheck() { |
| 25 | numHits = 0; | 25 | numHits = 0; |
| 26 | StartAddress = EndAddress = 0; | 26 | StartAddress = EndAddress = 0; |
| 27 | bRange = OnRead = OnWrite = Log = Break = false; | 27 | bRange = OnRead = OnWrite = Log = Break = false; |
| 28 | } | 28 | } |
| 29 | u32 StartAddress; | 29 | u32 StartAddress; |
| 30 | u32 EndAddress; | 30 | u32 EndAddress; |
| 31 | 31 | ||
| 32 | bool bRange; | 32 | bool bRange; |
| 33 | 33 | ||
| 34 | bool OnRead; | 34 | bool OnRead; |
| 35 | bool OnWrite; | 35 | bool OnWrite; |
| 36 | 36 | ||
| 37 | bool Log; | 37 | bool Log; |
| 38 | bool Break; | 38 | bool Break; |
| 39 | 39 | ||
| 40 | u32 numHits; | 40 | u32 numHits; |
| 41 | 41 | ||
| 42 | void Action(DebugInterface *dbg_interface, u32 _iValue, u32 addr, | 42 | void Action(DebugInterface *dbg_interface, u32 _iValue, u32 addr, |
| 43 | bool write, int size, u32 pc); | 43 | bool write, int size, u32 pc); |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | // Code breakpoints. | 46 | // Code breakpoints. |
| 47 | class BreakPoints | 47 | class BreakPoints |
| 48 | { | 48 | { |
| 49 | public: | 49 | public: |
| 50 | typedef std::vector<TBreakPoint> TBreakPoints; | 50 | typedef std::vector<TBreakPoint> TBreakPoints; |
| 51 | typedef std::vector<std::string> TBreakPointsStr; | 51 | typedef std::vector<std::string> TBreakPointsStr; |
| 52 | 52 | ||
| 53 | const TBreakPoints& GetBreakPoints() { return m_BreakPoints; } | 53 | const TBreakPoints& GetBreakPoints() { return m_BreakPoints; } |
| 54 | 54 | ||
| 55 | TBreakPointsStr GetStrings() const; | 55 | TBreakPointsStr GetStrings() const; |
| 56 | void AddFromStrings(const TBreakPointsStr& bps); | 56 | void AddFromStrings(const TBreakPointsStr& bps); |
| 57 | 57 | ||
| 58 | // is address breakpoint | 58 | // is address breakpoint |
| 59 | bool IsAddressBreakPoint(u32 _iAddress); | 59 | bool IsAddressBreakPoint(u32 _iAddress); |
| 60 | bool IsTempBreakPoint(u32 _iAddress); | 60 | bool IsTempBreakPoint(u32 _iAddress); |
| 61 | 61 | ||
| 62 | // Add BreakPoint | 62 | // Add BreakPoint |
| 63 | void Add(u32 em_address, bool temp=false); | 63 | void Add(u32 em_address, bool temp=false); |
| 64 | void Add(const TBreakPoint& bp); | 64 | void Add(const TBreakPoint& bp); |
| 65 | 65 | ||
| 66 | // Remove Breakpoint | 66 | // Remove Breakpoint |
| 67 | void Remove(u32 _iAddress); | 67 | void Remove(u32 _iAddress); |
| 68 | void Clear(); | 68 | void Clear(); |
| 69 | 69 | ||
| 70 | void DeleteByAddress(u32 _Address); | 70 | void DeleteByAddress(u32 _Address); |
| 71 | 71 | ||
| 72 | private: | 72 | private: |
| 73 | TBreakPoints m_BreakPoints; | 73 | TBreakPoints m_BreakPoints; |
| 74 | u32 m_iBreakOnCount; | 74 | u32 m_iBreakOnCount; |
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | 77 | ||
| @@ -79,23 +79,23 @@ private: | |||
| 79 | class MemChecks | 79 | class MemChecks |
| 80 | { | 80 | { |
| 81 | public: | 81 | public: |
| 82 | typedef std::vector<TMemCheck> TMemChecks; | 82 | typedef std::vector<TMemCheck> TMemChecks; |
| 83 | typedef std::vector<std::string> TMemChecksStr; | 83 | typedef std::vector<std::string> TMemChecksStr; |
| 84 | 84 | ||
| 85 | TMemChecks m_MemChecks; | 85 | TMemChecks m_MemChecks; |
| 86 | 86 | ||
| 87 | const TMemChecks& GetMemChecks() { return m_MemChecks; } | 87 | const TMemChecks& GetMemChecks() { return m_MemChecks; } |
| 88 | 88 | ||
| 89 | TMemChecksStr GetStrings() const; | 89 | TMemChecksStr GetStrings() const; |
| 90 | void AddFromStrings(const TMemChecksStr& mcs); | 90 | void AddFromStrings(const TMemChecksStr& mcs); |
| 91 | 91 | ||
| 92 | void Add(const TMemCheck& _rMemoryCheck); | 92 | void Add(const TMemCheck& _rMemoryCheck); |
| 93 | 93 | ||
| 94 | // memory breakpoint | 94 | // memory breakpoint |
| 95 | TMemCheck *GetMemCheck(u32 address); | 95 | TMemCheck *GetMemCheck(u32 address); |
| 96 | void Remove(u32 _Address); | 96 | void Remove(u32 _Address); |
| 97 | 97 | ||
| 98 | void Clear() { m_MemChecks.clear(); }; | 98 | void Clear() { m_MemChecks.clear(); }; |
| 99 | }; | 99 | }; |
| 100 | 100 | ||
| 101 | #endif | 101 | #endif |
diff --git a/src/common/src/chunk_file.h b/src/common/src/chunk_file.h index c480bc8ea..68c2943ab 100644 --- a/src/common/src/chunk_file.h +++ b/src/common/src/chunk_file.h | |||
| @@ -47,26 +47,26 @@ | |||
| 47 | 47 | ||
| 48 | #if defined(IOS) || defined(MACGNUSTD) | 48 | #if defined(IOS) || defined(MACGNUSTD) |
| 49 | namespace std { | 49 | namespace std { |
| 50 | using tr1::is_pointer; | 50 | using tr1::is_pointer; |
| 51 | } | 51 | } |
| 52 | #endif | 52 | #endif |
| 53 | #ifdef __SYMBIAN32__ | 53 | #ifdef __SYMBIAN32__ |
| 54 | namespace std { | 54 | namespace std { |
| 55 | template <bool bool_value> | 55 | template <bool bool_value> |
| 56 | struct bool_constant { | 56 | struct bool_constant { |
| 57 | typedef bool_constant<bool_value> type; | 57 | typedef bool_constant<bool_value> type; |
| 58 | static const bool value = bool_value; | 58 | static const bool value = bool_value; |
| 59 | }; | 59 | }; |
| 60 | template <bool bool_value> const bool bool_constant<bool_value>::value; | 60 | template <bool bool_value> const bool bool_constant<bool_value>::value; |
| 61 | template <typename T> struct is_pointer : public bool_constant<false> {}; | 61 | template <typename T> struct is_pointer : public bool_constant<false> {}; |
| 62 | template <typename T> struct is_pointer<T*> : public bool_constant<true> {}; | 62 | template <typename T> struct is_pointer<T*> : public bool_constant<true> {}; |
| 63 | } | 63 | } |
| 64 | #endif | 64 | #endif |
| 65 | 65 | ||
| 66 | template <class T> | 66 | template <class T> |
| 67 | struct LinkedListItem : public T | 67 | struct LinkedListItem : public T |
| 68 | { | 68 | { |
| 69 | LinkedListItem<T> *next; | 69 | LinkedListItem<T> *next; |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | class PointerWrap; | 72 | class PointerWrap; |
| @@ -74,801 +74,801 @@ class PointerWrap; | |||
| 74 | class PointerWrapSection | 74 | class PointerWrapSection |
| 75 | { | 75 | { |
| 76 | public: | 76 | public: |
| 77 | PointerWrapSection(PointerWrap &p, int ver, const char *title) : p_(p), ver_(ver), title_(title) { | 77 | PointerWrapSection(PointerWrap &p, int ver, const char *title) : p_(p), ver_(ver), title_(title) { |
| 78 | } | 78 | } |
| 79 | ~PointerWrapSection(); | 79 | ~PointerWrapSection(); |
| 80 | 80 | ||
| 81 | bool operator == (const int &v) const { return ver_ == v; } | 81 | bool operator == (const int &v) const { return ver_ == v; } |
| 82 | bool operator != (const int &v) const { return ver_ != v; } | 82 | bool operator != (const int &v) const { return ver_ != v; } |
| 83 | bool operator <= (const int &v) const { return ver_ <= v; } | 83 | bool operator <= (const int &v) const { return ver_ <= v; } |
| 84 | bool operator >= (const int &v) const { return ver_ >= v; } | 84 | bool operator >= (const int &v) const { return ver_ >= v; } |
| 85 | bool operator < (const int &v) const { return ver_ < v; } | 85 | bool operator < (const int &v) const { return ver_ < v; } |
| 86 | bool operator > (const int &v) const { return ver_ > v; } | 86 | bool operator > (const int &v) const { return ver_ > v; } |
| 87 | 87 | ||
| 88 | operator bool() const { | 88 | operator bool() const { |
| 89 | return ver_ > 0; | 89 | return ver_ > 0; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | private: | 92 | private: |
| 93 | PointerWrap &p_; | 93 | PointerWrap &p_; |
| 94 | int ver_; | 94 | int ver_; |
| 95 | const char *title_; | 95 | const char *title_; |
| 96 | }; | 96 | }; |
| 97 | 97 | ||
| 98 | // Wrapper class | 98 | // Wrapper class |
| 99 | class PointerWrap | 99 | class PointerWrap |
| 100 | { | 100 | { |
| 101 | // This makes it a compile error if you forget to define DoState() on non-POD. | 101 | // This makes it a compile error if you forget to define DoState() on non-POD. |
| 102 | // Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason... | 102 | // Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason... |
| 103 | #ifdef _MSC_VER | 103 | #ifdef _MSC_VER |
| 104 | template<typename T, bool isPOD = std::is_pod<T>::value, bool isPointer = std::is_pointer<T>::value> | 104 | template<typename T, bool isPOD = std::is_pod<T>::value, bool isPointer = std::is_pointer<T>::value> |
| 105 | #else | 105 | #else |
| 106 | template<typename T, bool isPOD = __is_pod(T), bool isPointer = std::is_pointer<T>::value> | 106 | template<typename T, bool isPOD = __is_pod(T), bool isPointer = std::is_pointer<T>::value> |
| 107 | #endif | 107 | #endif |
| 108 | struct DoHelper | 108 | struct DoHelper |
| 109 | { | 109 | { |
| 110 | static void DoArray(PointerWrap *p, T *x, int count) | 110 | static void DoArray(PointerWrap *p, T *x, int count) |
| 111 | { | 111 | { |
| 112 | for (int i = 0; i < count; ++i) | 112 | for (int i = 0; i < count; ++i) |
| 113 | p->Do(x[i]); | 113 | p->Do(x[i]); |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | static void Do(PointerWrap *p, T &x) | 116 | static void Do(PointerWrap *p, T &x) |
| 117 | { | 117 | { |
| 118 | p->DoClass(x); | 118 | p->DoClass(x); |
| 119 | } | 119 | } |
| 120 | }; | 120 | }; |
| 121 | 121 | ||
| 122 | template<typename T> | 122 | template<typename T> |
| 123 | struct DoHelper<T, true, false> | 123 | struct DoHelper<T, true, false> |
| 124 | { | 124 | { |
| 125 | static void DoArray(PointerWrap *p, T *x, int count) | 125 | static void DoArray(PointerWrap *p, T *x, int count) |
| 126 | { | 126 | { |
| 127 | p->DoVoid((void *)x, sizeof(T) * count); | 127 | p->DoVoid((void *)x, sizeof(T) * count); |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | static void Do(PointerWrap *p, T &x) | 130 | static void Do(PointerWrap *p, T &x) |
| 131 | { | 131 | { |
| 132 | p->DoVoid((void *)&x, sizeof(x)); | 132 | p->DoVoid((void *)&x, sizeof(x)); |
| 133 | } | 133 | } |
| 134 | }; | 134 | }; |
| 135 | 135 | ||
| 136 | public: | 136 | public: |
| 137 | enum Mode { | 137 | enum Mode { |
| 138 | MODE_READ = 1, // load | 138 | MODE_READ = 1, // load |
| 139 | MODE_WRITE, // save | 139 | MODE_WRITE, // save |
| 140 | MODE_MEASURE, // calculate size | 140 | MODE_MEASURE, // calculate size |
| 141 | MODE_VERIFY, // compare | 141 | MODE_VERIFY, // compare |
| 142 | }; | 142 | }; |
| 143 | 143 | ||
| 144 | enum Error { | 144 | enum Error { |
| 145 | ERROR_NONE = 0, | 145 | ERROR_NONE = 0, |
| 146 | ERROR_WARNING = 1, | 146 | ERROR_WARNING = 1, |
| 147 | ERROR_FAILURE = 2, | 147 | ERROR_FAILURE = 2, |
| 148 | }; | 148 | }; |
| 149 | 149 | ||
| 150 | u8 **ptr; | 150 | u8 **ptr; |
| 151 | Mode mode; | 151 | Mode mode; |
| 152 | Error error; | 152 | Error error; |
| 153 | 153 | ||
| 154 | public: | 154 | public: |
| 155 | PointerWrap(u8 **ptr_, Mode mode_) : ptr(ptr_), mode(mode_), error(ERROR_NONE) {} | 155 | PointerWrap(u8 **ptr_, Mode mode_) : ptr(ptr_), mode(mode_), error(ERROR_NONE) {} |
| 156 | PointerWrap(unsigned char **ptr_, int mode_) : ptr((u8**)ptr_), mode((Mode)mode_), error(ERROR_NONE) {} | 156 | PointerWrap(unsigned char **ptr_, int mode_) : ptr((u8**)ptr_), mode((Mode)mode_), error(ERROR_NONE) {} |
| 157 | 157 | ||
| 158 | PointerWrapSection Section(const char *title, int ver) { | 158 | PointerWrapSection Section(const char *title, int ver) { |
| 159 | return Section(title, ver, ver); | 159 | return Section(title, ver, ver); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | // The returned object can be compared against the version that was loaded. | 162 | // The returned object can be compared against the version that was loaded. |
| 163 | // This can be used to support versions as old as minVer. | 163 | // This can be used to support versions as old as minVer. |
| 164 | // Version = 0 means the section was not found. | 164 | // Version = 0 means the section was not found. |
| 165 | PointerWrapSection Section(const char *title, int minVer, int ver) { | 165 | PointerWrapSection Section(const char *title, int minVer, int ver) { |
| 166 | char marker[16] = {0}; | 166 | char marker[16] = {0}; |
| 167 | int foundVersion = ver; | 167 | int foundVersion = ver; |
| 168 | 168 | ||
| 169 | strncpy(marker, title, sizeof(marker)); | 169 | strncpy(marker, title, sizeof(marker)); |
| 170 | if (!ExpectVoid(marker, sizeof(marker))) | 170 | if (!ExpectVoid(marker, sizeof(marker))) |
| 171 | { | 171 | { |
| 172 | // Might be before we added name markers for safety. | 172 | // Might be before we added name markers for safety. |
| 173 | if (foundVersion == 1 && ExpectVoid(&foundVersion, sizeof(foundVersion))) | 173 | if (foundVersion == 1 && ExpectVoid(&foundVersion, sizeof(foundVersion))) |
| 174 | DoMarker(title); | 174 | DoMarker(title); |
| 175 | // Wasn't found, but maybe we can still load the state. | 175 | // Wasn't found, but maybe we can still load the state. |
| 176 | else | 176 | else |
| 177 | foundVersion = 0; | 177 | foundVersion = 0; |
| 178 | } | 178 | } |
| 179 | else | 179 | else |
| 180 | Do(foundVersion); | 180 | Do(foundVersion); |
| 181 | 181 | ||
| 182 | if (error == ERROR_FAILURE || foundVersion < minVer || foundVersion > ver) { | 182 | if (error == ERROR_FAILURE || foundVersion < minVer || foundVersion > ver) { |
| 183 | WARN_LOG(COMMON, "Savestate failure: wrong version %d found for %s", foundVersion, title); | 183 | WARN_LOG(COMMON, "Savestate failure: wrong version %d found for %s", foundVersion, title); |
| 184 | SetError(ERROR_FAILURE); | 184 | SetError(ERROR_FAILURE); |
| 185 | return PointerWrapSection(*this, -1, title); | 185 | return PointerWrapSection(*this, -1, title); |
| 186 | } | 186 | } |
| 187 | return PointerWrapSection(*this, foundVersion, title); | 187 | return PointerWrapSection(*this, foundVersion, title); |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | void SetMode(Mode mode_) {mode = mode_;} | 190 | void SetMode(Mode mode_) {mode = mode_;} |
| 191 | Mode GetMode() const {return mode;} | 191 | Mode GetMode() const {return mode;} |
| 192 | u8 **GetPPtr() {return ptr;} | 192 | u8 **GetPPtr() {return ptr;} |
| 193 | void SetError(Error error_) | 193 | void SetError(Error error_) |
| 194 | { | 194 | { |
| 195 | if (error < error_) | 195 | if (error < error_) |
| 196 | error = error_; | 196 | error = error_; |
| 197 | if (error > ERROR_WARNING) | 197 | if (error > ERROR_WARNING) |
| 198 | mode = PointerWrap::MODE_MEASURE; | 198 | mode = PointerWrap::MODE_MEASURE; |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | bool ExpectVoid(void *data, int size) | 201 | bool ExpectVoid(void *data, int size) |
| 202 | { | 202 | { |
| 203 | switch (mode) { | 203 | switch (mode) { |
| 204 | case MODE_READ: if (memcmp(data, *ptr, size) != 0) return false; break; | 204 | case MODE_READ: if (memcmp(data, *ptr, size) != 0) return false; break; |
| 205 | case MODE_WRITE: memcpy(*ptr, data, size); break; | 205 | case MODE_WRITE: memcpy(*ptr, data, size); break; |
| 206 | case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything | 206 | case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything |
| 207 | case MODE_VERIFY: for(int i = 0; i < size; i++) _dbg_assert_msg_(COMMON, ((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], &(*ptr)[i]); break; | 207 | case MODE_VERIFY: for(int i = 0; i < size; i++) _dbg_assert_msg_(COMMON, ((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], &(*ptr)[i]); break; |
| 208 | default: break; // throw an error? | 208 | default: break; // throw an error? |
| 209 | } | 209 | } |
| 210 | (*ptr) += size; | 210 | (*ptr) += size; |
| 211 | return true; | 211 | return true; |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | void DoVoid(void *data, int size) | 214 | void DoVoid(void *data, int size) |
| 215 | { | 215 | { |
| 216 | switch (mode) { | 216 | switch (mode) { |
| 217 | case MODE_READ: memcpy(data, *ptr, size); break; | 217 | case MODE_READ: memcpy(data, *ptr, size); break; |
| 218 | case MODE_WRITE: memcpy(*ptr, data, size); break; | 218 | case MODE_WRITE: memcpy(*ptr, data, size); break; |
| 219 | case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything | 219 | case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything |
| 220 | case MODE_VERIFY: for(int i = 0; i < size; i++) _dbg_assert_msg_(COMMON, ((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], &(*ptr)[i]); break; | 220 | case MODE_VERIFY: for(int i = 0; i < size; i++) _dbg_assert_msg_(COMMON, ((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], &(*ptr)[i]); break; |
| 221 | default: break; // throw an error? | 221 | default: break; // throw an error? |
| 222 | } | 222 | } |
| 223 | (*ptr) += size; | 223 | (*ptr) += size; |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | template<class K, class T> | 226 | template<class K, class T> |
| 227 | void Do(std::map<K, T *> &x) | 227 | void Do(std::map<K, T *> &x) |
| 228 | { | 228 | { |
| 229 | if (mode == MODE_READ) | 229 | if (mode == MODE_READ) |
| 230 | { | 230 | { |
| 231 | for (auto it = x.begin(), end = x.end(); it != end; ++it) | 231 | for (auto it = x.begin(), end = x.end(); it != end; ++it) |
| 232 | { | 232 | { |
| 233 | if (it->second != NULL) | 233 | if (it->second != NULL) |
| 234 | delete it->second; | 234 | delete it->second; |
| 235 | } | 235 | } |
| 236 | } | 236 | } |
| 237 | T *dv = NULL; | 237 | T *dv = NULL; |
| 238 | DoMap(x, dv); | 238 | DoMap(x, dv); |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | template<class K, class T> | 241 | template<class K, class T> |
| 242 | void Do(std::map<K, T> &x) | 242 | void Do(std::map<K, T> &x) |
| 243 | { | 243 | { |
| 244 | T dv = T(); | 244 | T dv = T(); |
| 245 | DoMap(x, dv); | 245 | DoMap(x, dv); |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | template<class K, class T> | 248 | template<class K, class T> |
| 249 | void DoMap(std::map<K, T> &x, T &default_val) | 249 | void DoMap(std::map<K, T> &x, T &default_val) |
| 250 | { | 250 | { |
| 251 | unsigned int number = (unsigned int)x.size(); | 251 | unsigned int number = (unsigned int)x.size(); |
| 252 | Do(number); | 252 | Do(number); |
| 253 | switch (mode) { | 253 | switch (mode) { |
| 254 | case MODE_READ: | 254 | case MODE_READ: |
| 255 | { | 255 | { |
| 256 | x.clear(); | 256 | x.clear(); |
| 257 | while (number > 0) | 257 | while (number > 0) |
| 258 | { | 258 | { |
| 259 | K first = K(); | 259 | K first = K(); |
| 260 | Do(first); | 260 | Do(first); |
| 261 | T second = default_val; | 261 | T second = default_val; |
| 262 | Do(second); | 262 | Do(second); |
| 263 | x[first] = second; | 263 | x[first] = second; |
| 264 | --number; | 264 | --number; |
| 265 | } | 265 | } |
| 266 | } | 266 | } |
| 267 | break; | 267 | break; |
| 268 | case MODE_WRITE: | 268 | case MODE_WRITE: |
| 269 | case MODE_MEASURE: | 269 | case MODE_MEASURE: |
| 270 | case MODE_VERIFY: | 270 | case MODE_VERIFY: |
| 271 | { | 271 | { |
| 272 | typename std::map<K, T>::iterator itr = x.begin(); | 272 | typename std::map<K, T>::iterator itr = x.begin(); |
| 273 | while (number > 0) | 273 | while (number > 0) |
| 274 | { | 274 | { |
| 275 | K first = itr->first; | 275 | K first = itr->first; |
| 276 | Do(first); | 276 | Do(first); |
| 277 | Do(itr->second); | 277 | Do(itr->second); |
| 278 | --number; | 278 | --number; |
| 279 | ++itr; | 279 | ++itr; |
| 280 | } | 280 | } |
| 281 | } | 281 | } |
| 282 | break; | 282 | break; |
| 283 | } | 283 | } |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | template<class K, class T> | 286 | template<class K, class T> |
| 287 | void Do(std::multimap<K, T *> &x) | 287 | void Do(std::multimap<K, T *> &x) |
| 288 | { | 288 | { |
| 289 | if (mode == MODE_READ) | 289 | if (mode == MODE_READ) |
| 290 | { | 290 | { |
| 291 | for (auto it = x.begin(), end = x.end(); it != end; ++it) | 291 | for (auto it = x.begin(), end = x.end(); it != end; ++it) |
| 292 | { | 292 | { |
| 293 | if (it->second != NULL) | 293 | if (it->second != NULL) |
| 294 | delete it->second; | 294 | delete it->second; |
| 295 | } | 295 | } |
| 296 | } | 296 | } |
| 297 | T *dv = NULL; | 297 | T *dv = NULL; |
| 298 | DoMultimap(x, dv); | 298 | DoMultimap(x, dv); |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | template<class K, class T> | 301 | template<class K, class T> |
| 302 | void Do(std::multimap<K, T> &x) | 302 | void Do(std::multimap<K, T> &x) |
| 303 | { | 303 | { |
| 304 | T dv = T(); | 304 | T dv = T(); |
| 305 | DoMultimap(x, dv); | 305 | DoMultimap(x, dv); |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | template<class K, class T> | 308 | template<class K, class T> |
| 309 | void DoMultimap(std::multimap<K, T> &x, T &default_val) | 309 | void DoMultimap(std::multimap<K, T> &x, T &default_val) |
| 310 | { | 310 | { |
| 311 | unsigned int number = (unsigned int)x.size(); | 311 | unsigned int number = (unsigned int)x.size(); |
| 312 | Do(number); | 312 | Do(number); |
| 313 | switch (mode) { | 313 | switch (mode) { |
| 314 | case MODE_READ: | 314 | case MODE_READ: |
| 315 | { | 315 | { |
| 316 | x.clear(); | 316 | x.clear(); |
| 317 | while (number > 0) | 317 | while (number > 0) |
| 318 | { | 318 | { |
| 319 | K first = K(); | 319 | K first = K(); |
| 320 | Do(first); | 320 | Do(first); |
| 321 | T second = default_val; | 321 | T second = default_val; |
| 322 | Do(second); | 322 | Do(second); |
| 323 | x.insert(std::make_pair(first, second)); | 323 | x.insert(std::make_pair(first, second)); |
| 324 | --number; | 324 | --number; |
| 325 | } | 325 | } |
| 326 | } | 326 | } |
| 327 | break; | 327 | break; |
| 328 | case MODE_WRITE: | 328 | case MODE_WRITE: |
| 329 | case MODE_MEASURE: | 329 | case MODE_MEASURE: |
| 330 | case MODE_VERIFY: | 330 | case MODE_VERIFY: |
| 331 | { | 331 | { |
| 332 | typename std::multimap<K, T>::iterator itr = x.begin(); | 332 | typename std::multimap<K, T>::iterator itr = x.begin(); |
| 333 | while (number > 0) | 333 | while (number > 0) |
| 334 | { | 334 | { |
| 335 | Do(itr->first); | 335 | Do(itr->first); |
| 336 | Do(itr->second); | 336 | Do(itr->second); |
| 337 | --number; | 337 | --number; |
| 338 | ++itr; | 338 | ++itr; |
| 339 | } | 339 | } |
| 340 | } | 340 | } |
| 341 | break; | 341 | break; |
| 342 | } | 342 | } |
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | // Store vectors. | 345 | // Store vectors. |
| 346 | template<class T> | 346 | template<class T> |
| 347 | void Do(std::vector<T *> &x) | 347 | void Do(std::vector<T *> &x) |
| 348 | { | 348 | { |
| 349 | T *dv = NULL; | 349 | T *dv = NULL; |
| 350 | DoVector(x, dv); | 350 | DoVector(x, dv); |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | template<class T> | 353 | template<class T> |
| 354 | void Do(std::vector<T> &x) | 354 | void Do(std::vector<T> &x) |
| 355 | { | 355 | { |
| 356 | T dv = T(); | 356 | T dv = T(); |
| 357 | DoVector(x, dv); | 357 | DoVector(x, dv); |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | 360 | ||
| 361 | template<class T> | 361 | template<class T> |
| 362 | void DoPOD(std::vector<T> &x) | 362 | void DoPOD(std::vector<T> &x) |
| 363 | { | 363 | { |
| 364 | T dv = T(); | 364 | T dv = T(); |
| 365 | DoVectorPOD(x, dv); | 365 | DoVectorPOD(x, dv); |
| 366 | } | 366 | } |
| 367 | 367 | ||
| 368 | template<class T> | 368 | template<class T> |
| 369 | void Do(std::vector<T> &x, T &default_val) | 369 | void Do(std::vector<T> &x, T &default_val) |
| 370 | { | 370 | { |
| 371 | DoVector(x, default_val); | 371 | DoVector(x, default_val); |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | template<class T> | 374 | template<class T> |
| 375 | void DoVector(std::vector<T> &x, T &default_val) | 375 | void DoVector(std::vector<T> &x, T &default_val) |
| 376 | { | 376 | { |
| 377 | u32 vec_size = (u32)x.size(); | 377 | u32 vec_size = (u32)x.size(); |
| 378 | Do(vec_size); | 378 | Do(vec_size); |
| 379 | x.resize(vec_size, default_val); | 379 | x.resize(vec_size, default_val); |
| 380 | if (vec_size > 0) | 380 | if (vec_size > 0) |
| 381 | DoArray(&x[0], vec_size); | 381 | DoArray(&x[0], vec_size); |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | template<class T> | 384 | template<class T> |
| 385 | void DoVectorPOD(std::vector<T> &x, T &default_val) | 385 | void DoVectorPOD(std::vector<T> &x, T &default_val) |
| 386 | { | 386 | { |
| 387 | u32 vec_size = (u32)x.size(); | 387 | u32 vec_size = (u32)x.size(); |
| 388 | Do(vec_size); | 388 | Do(vec_size); |
| 389 | x.resize(vec_size, default_val); | 389 | x.resize(vec_size, default_val); |
| 390 | if (vec_size > 0) | 390 | if (vec_size > 0) |
| 391 | DoArray(&x[0], vec_size); | 391 | DoArray(&x[0], vec_size); |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | // Store deques. | 394 | // Store deques. |
| 395 | template<class T> | 395 | template<class T> |
| 396 | void Do(std::deque<T *> &x) | 396 | void Do(std::deque<T *> &x) |
| 397 | { | 397 | { |
| 398 | T *dv = NULL; | 398 | T *dv = NULL; |
| 399 | DoDeque(x, dv); | 399 | DoDeque(x, dv); |
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | template<class T> | 402 | template<class T> |
| 403 | void Do(std::deque<T> &x) | 403 | void Do(std::deque<T> &x) |
| 404 | { | 404 | { |
| 405 | T dv = T(); | 405 | T dv = T(); |
| 406 | DoDeque(x, dv); | 406 | DoDeque(x, dv); |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | template<class T> | 409 | template<class T> |
| 410 | void DoDeque(std::deque<T> &x, T &default_val) | 410 | void DoDeque(std::deque<T> &x, T &default_val) |
| 411 | { | 411 | { |
| 412 | u32 deq_size = (u32)x.size(); | 412 | u32 deq_size = (u32)x.size(); |
| 413 | Do(deq_size); | 413 | Do(deq_size); |
| 414 | x.resize(deq_size, default_val); | 414 | x.resize(deq_size, default_val); |
| 415 | u32 i; | 415 | u32 i; |
| 416 | for(i = 0; i < deq_size; i++) | 416 | for(i = 0; i < deq_size; i++) |
| 417 | Do(x[i]); | 417 | Do(x[i]); |
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | // Store STL lists. | 420 | // Store STL lists. |
| 421 | template<class T> | 421 | template<class T> |
| 422 | void Do(std::list<T *> &x) | 422 | void Do(std::list<T *> &x) |
| 423 | { | 423 | { |
| 424 | T *dv = NULL; | 424 | T *dv = NULL; |
| 425 | Do(x, dv); | 425 | Do(x, dv); |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | template<class T> | 428 | template<class T> |
| 429 | void Do(std::list<T> &x) | 429 | void Do(std::list<T> &x) |
| 430 | { | 430 | { |
| 431 | T dv = T(); | 431 | T dv = T(); |
| 432 | DoList(x, dv); | 432 | DoList(x, dv); |
| 433 | } | 433 | } |
| 434 | 434 | ||
| 435 | template<class T> | 435 | template<class T> |
| 436 | void Do(std::list<T> &x, T &default_val) | 436 | void Do(std::list<T> &x, T &default_val) |
| 437 | { | 437 | { |
| 438 | DoList(x, default_val); | 438 | DoList(x, default_val); |
| 439 | } | 439 | } |
| 440 | 440 | ||
| 441 | template<class T> | 441 | template<class T> |
| 442 | void DoList(std::list<T> &x, T &default_val) | 442 | void DoList(std::list<T> &x, T &default_val) |
| 443 | { | 443 | { |
| 444 | u32 list_size = (u32)x.size(); | 444 | u32 list_size = (u32)x.size(); |
| 445 | Do(list_size); | 445 | Do(list_size); |
| 446 | x.resize(list_size, default_val); | 446 | x.resize(list_size, default_val); |
| 447 | 447 | ||
| 448 | typename std::list<T>::iterator itr, end; | 448 | typename std::list<T>::iterator itr, end; |
| 449 | for (itr = x.begin(), end = x.end(); itr != end; ++itr) | 449 | for (itr = x.begin(), end = x.end(); itr != end; ++itr) |
| 450 | Do(*itr); | 450 | Do(*itr); |
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | 453 | ||
| 454 | // Store STL sets. | 454 | // Store STL sets. |
| 455 | template <class T> | 455 | template <class T> |
| 456 | void Do(std::set<T *> &x) | 456 | void Do(std::set<T *> &x) |
| 457 | { | 457 | { |
| 458 | if (mode == MODE_READ) | 458 | if (mode == MODE_READ) |
| 459 | { | 459 | { |
| 460 | for (auto it = x.begin(), end = x.end(); it != end; ++it) | 460 | for (auto it = x.begin(), end = x.end(); it != end; ++it) |
| 461 | { | 461 | { |
| 462 | if (*it != NULL) | 462 | if (*it != NULL) |
| 463 | delete *it; | 463 | delete *it; |
| 464 | } | 464 | } |
| 465 | } | 465 | } |
| 466 | DoSet(x); | 466 | DoSet(x); |
| 467 | } | 467 | } |
| 468 | 468 | ||
| 469 | template <class T> | 469 | template <class T> |
| 470 | void Do(std::set<T> &x) | 470 | void Do(std::set<T> &x) |
| 471 | { | 471 | { |
| 472 | DoSet(x); | 472 | DoSet(x); |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | template <class T> | 475 | template <class T> |
| 476 | void DoSet(std::set<T> &x) | 476 | void DoSet(std::set<T> &x) |
| 477 | { | 477 | { |
| 478 | unsigned int number = (unsigned int)x.size(); | 478 | unsigned int number = (unsigned int)x.size(); |
| 479 | Do(number); | 479 | Do(number); |
| 480 | 480 | ||
| 481 | switch (mode) | 481 | switch (mode) |
| 482 | { | 482 | { |
| 483 | case MODE_READ: | 483 | case MODE_READ: |
| 484 | { | 484 | { |
| 485 | x.clear(); | 485 | x.clear(); |
| 486 | while (number-- > 0) | 486 | while (number-- > 0) |
| 487 | { | 487 | { |
| 488 | T it = T(); | 488 | T it = T(); |
| 489 | Do(it); | 489 | Do(it); |
| 490 | x.insert(it); | 490 | x.insert(it); |
| 491 | } | 491 | } |
| 492 | } | 492 | } |
| 493 | break; | 493 | break; |
| 494 | case MODE_WRITE: | 494 | case MODE_WRITE: |
| 495 | case MODE_MEASURE: | 495 | case MODE_MEASURE: |
| 496 | case MODE_VERIFY: | 496 | case MODE_VERIFY: |
| 497 | { | 497 | { |
| 498 | typename std::set<T>::iterator itr = x.begin(); | 498 | typename std::set<T>::iterator itr = x.begin(); |
| 499 | while (number-- > 0) | 499 | while (number-- > 0) |
| 500 | Do(*itr++); | 500 | Do(*itr++); |
| 501 | } | 501 | } |
| 502 | break; | 502 | break; |
| 503 | 503 | ||
| 504 | default: | 504 | default: |
| 505 | ERROR_LOG(COMMON, "Savestate error: invalid mode %d.", mode); | 505 | ERROR_LOG(COMMON, "Savestate error: invalid mode %d.", mode); |
| 506 | } | 506 | } |
| 507 | } | 507 | } |
| 508 | 508 | ||
| 509 | // Store strings. | 509 | // Store strings. |
| 510 | void Do(std::string &x) | 510 | void Do(std::string &x) |
| 511 | { | 511 | { |
| 512 | int stringLen = (int)x.length() + 1; | 512 | int stringLen = (int)x.length() + 1; |
| 513 | Do(stringLen); | 513 | Do(stringLen); |
| 514 | 514 | ||
| 515 | switch (mode) { | 515 | switch (mode) { |
| 516 | case MODE_READ: x = (char*)*ptr; break; | 516 | case MODE_READ: x = (char*)*ptr; break; |
| 517 | case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; | 517 | case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; |
| 518 | case MODE_MEASURE: break; | 518 | case MODE_MEASURE: break; |
| 519 | case MODE_VERIFY: _dbg_assert_msg_(COMMON, !strcmp(x.c_str(), (char*)*ptr), "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", x.c_str(), (char*)*ptr, ptr); break; | 519 | case MODE_VERIFY: _dbg_assert_msg_(COMMON, !strcmp(x.c_str(), (char*)*ptr), "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", x.c_str(), (char*)*ptr, ptr); break; |
| 520 | } | 520 | } |
| 521 | (*ptr) += stringLen; | 521 | (*ptr) += stringLen; |
| 522 | } | 522 | } |
| 523 | 523 | ||
| 524 | void Do(std::wstring &x) | 524 | void Do(std::wstring &x) |
| 525 | { | 525 | { |
| 526 | int stringLen = sizeof(wchar_t)*((int)x.length() + 1); | 526 | int stringLen = sizeof(wchar_t)*((int)x.length() + 1); |
| 527 | Do(stringLen); | 527 | Do(stringLen); |
| 528 | 528 | ||
| 529 | switch (mode) { | 529 | switch (mode) { |
| 530 | case MODE_READ: x = (wchar_t*)*ptr; break; | 530 | case MODE_READ: x = (wchar_t*)*ptr; break; |
| 531 | case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; | 531 | case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; |
| 532 | case MODE_MEASURE: break; | 532 | case MODE_MEASURE: break; |
| 533 | case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (wchar_t*)*ptr, "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break; | 533 | case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (wchar_t*)*ptr, "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break; |
| 534 | } | 534 | } |
| 535 | (*ptr) += stringLen; | 535 | (*ptr) += stringLen; |
| 536 | } | 536 | } |
| 537 | 537 | ||
| 538 | template<class T> | 538 | template<class T> |
| 539 | void DoClass(T &x) { | 539 | void DoClass(T &x) { |
| 540 | x.DoState(*this); | 540 | x.DoState(*this); |
| 541 | } | 541 | } |
| 542 | 542 | ||
| 543 | template<class T> | 543 | template<class T> |
| 544 | void DoClass(T *&x) { | 544 | void DoClass(T *&x) { |
| 545 | if (mode == MODE_READ) | 545 | if (mode == MODE_READ) |
| 546 | { | 546 | { |
| 547 | if (x != NULL) | 547 | if (x != NULL) |
| 548 | delete x; | 548 | delete x; |
| 549 | x = new T(); | 549 | x = new T(); |
| 550 | } | 550 | } |
| 551 | x->DoState(*this); | 551 | x->DoState(*this); |
| 552 | } | 552 | } |
| 553 | 553 | ||
| 554 | template<class T> | 554 | template<class T> |
| 555 | void DoArray(T *x, int count) { | 555 | void DoArray(T *x, int count) { |
| 556 | DoHelper<T>::DoArray(this, x, count); | 556 | DoHelper<T>::DoArray(this, x, count); |
| 557 | } | 557 | } |
| 558 | 558 | ||
| 559 | template<class T> | 559 | template<class T> |
| 560 | void Do(T &x) { | 560 | void Do(T &x) { |
| 561 | DoHelper<T>::Do(this, x); | 561 | DoHelper<T>::Do(this, x); |
| 562 | } | 562 | } |
| 563 | 563 | ||
| 564 | template<class T> | 564 | template<class T> |
| 565 | void DoPOD(T &x) { | 565 | void DoPOD(T &x) { |
| 566 | DoHelper<T>::Do(this, x); | 566 | DoHelper<T>::Do(this, x); |
| 567 | } | 567 | } |
| 568 | 568 | ||
| 569 | template<class T> | 569 | template<class T> |
| 570 | void DoPointer(T* &x, T*const base) { | 570 | void DoPointer(T* &x, T*const base) { |
| 571 | // pointers can be more than 2^31 apart, but you're using this function wrong if you need that much range | 571 | // pointers can be more than 2^31 apart, but you're using this function wrong if you need that much range |
| 572 | s32 offset = x - base; | 572 | s32 offset = x - base; |
| 573 | Do(offset); | 573 | Do(offset); |
| 574 | if (mode == MODE_READ) | 574 | if (mode == MODE_READ) |
| 575 | x = base + offset; | 575 | x = base + offset; |
| 576 | } | 576 | } |
| 577 | 577 | ||
| 578 | template<class T, LinkedListItem<T>* (*TNew)(), void (*TFree)(LinkedListItem<T>*), void (*TDo)(PointerWrap&, T*)> | 578 | template<class T, LinkedListItem<T>* (*TNew)(), void (*TFree)(LinkedListItem<T>*), void (*TDo)(PointerWrap&, T*)> |
| 579 | void DoLinkedList(LinkedListItem<T>*& list_start, LinkedListItem<T>** list_end=0) | 579 | void DoLinkedList(LinkedListItem<T>*& list_start, LinkedListItem<T>** list_end=0) |
| 580 | { | 580 | { |
| 581 | LinkedListItem<T>* list_cur = list_start; | 581 | LinkedListItem<T>* list_cur = list_start; |
| 582 | LinkedListItem<T>* prev = 0; | 582 | LinkedListItem<T>* prev = 0; |
| 583 | 583 | ||
| 584 | while (true) | 584 | while (true) |
| 585 | { | 585 | { |
| 586 | u8 shouldExist = (list_cur ? 1 : 0); | 586 | u8 shouldExist = (list_cur ? 1 : 0); |
| 587 | Do(shouldExist); | 587 | Do(shouldExist); |
| 588 | if (shouldExist == 1) | 588 | if (shouldExist == 1) |
| 589 | { | 589 | { |
| 590 | LinkedListItem<T>* cur = list_cur ? list_cur : TNew(); | 590 | LinkedListItem<T>* cur = list_cur ? list_cur : TNew(); |
| 591 | TDo(*this, (T*)cur); | 591 | TDo(*this, (T*)cur); |
| 592 | if (!list_cur) | 592 | if (!list_cur) |
| 593 | { | 593 | { |
| 594 | if (mode == MODE_READ) | 594 | if (mode == MODE_READ) |
| 595 | { | 595 | { |
| 596 | cur->next = 0; | 596 | cur->next = 0; |
| 597 | list_cur = cur; | 597 | list_cur = cur; |
| 598 | if (prev) | 598 | if (prev) |
| 599 | prev->next = cur; | 599 | prev->next = cur; |
| 600 | else | 600 | else |
| 601 | list_start = cur; | 601 | list_start = cur; |
| 602 | } | 602 | } |
| 603 | else | 603 | else |
| 604 | { | 604 | { |
| 605 | TFree(cur); | 605 | TFree(cur); |
| 606 | continue; | 606 | continue; |
| 607 | } | 607 | } |
| 608 | } | 608 | } |
| 609 | } | 609 | } |
| 610 | else | 610 | else |
| 611 | { | 611 | { |
| 612 | if (mode == MODE_READ) | 612 | if (mode == MODE_READ) |
| 613 | { | 613 | { |
| 614 | if (prev) | 614 | if (prev) |
| 615 | prev->next = 0; | 615 | prev->next = 0; |
| 616 | if (list_end) | 616 | if (list_end) |
| 617 | *list_end = prev; | 617 | *list_end = prev; |
| 618 | if (list_cur) | 618 | if (list_cur) |
| 619 | { | 619 | { |
| 620 | if (list_start == list_cur) | 620 | if (list_start == list_cur) |
| 621 | list_start = 0; | 621 | list_start = 0; |
| 622 | do | 622 | do |
| 623 | { | 623 | { |
| 624 | LinkedListItem<T>* next = list_cur->next; | 624 | LinkedListItem<T>* next = list_cur->next; |
| 625 | TFree(list_cur); | 625 | TFree(list_cur); |
| 626 | list_cur = next; | 626 | list_cur = next; |
| 627 | } | 627 | } |
| 628 | while (list_cur); | 628 | while (list_cur); |
| 629 | } | 629 | } |
| 630 | } | 630 | } |
| 631 | break; | 631 | break; |
| 632 | } | 632 | } |
| 633 | prev = list_cur; | 633 | prev = list_cur; |
| 634 | list_cur = list_cur->next; | 634 | list_cur = list_cur->next; |
| 635 | } | 635 | } |
| 636 | } | 636 | } |
| 637 | 637 | ||
| 638 | void DoMarker(const char* prevName, u32 arbitraryNumber=0x42) | 638 | void DoMarker(const char* prevName, u32 arbitraryNumber=0x42) |
| 639 | { | 639 | { |
| 640 | u32 cookie = arbitraryNumber; | 640 | u32 cookie = arbitraryNumber; |
| 641 | Do(cookie); | 641 | Do(cookie); |
| 642 | if(mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) | 642 | if(mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) |
| 643 | { | 643 | { |
| 644 | PanicAlertT("Error: After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). Aborting savestate load...", prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); | 644 | PanicAlertT("Error: After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). Aborting savestate load...", prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); |
| 645 | SetError(ERROR_FAILURE); | 645 | SetError(ERROR_FAILURE); |
| 646 | } | 646 | } |
| 647 | } | 647 | } |
| 648 | }; | 648 | }; |
| 649 | 649 | ||
| 650 | inline PointerWrapSection::~PointerWrapSection() { | 650 | inline PointerWrapSection::~PointerWrapSection() { |
| 651 | if (ver_ > 0) { | 651 | if (ver_ > 0) { |
| 652 | p_.DoMarker(title_); | 652 | p_.DoMarker(title_); |
| 653 | } | 653 | } |
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | 656 | ||
| 657 | class CChunkFileReader | 657 | class CChunkFileReader |
| 658 | { | 658 | { |
| 659 | public: | 659 | public: |
| 660 | enum Error { | 660 | enum Error { |
| 661 | ERROR_NONE, | 661 | ERROR_NONE, |
| 662 | ERROR_BAD_FILE, | 662 | ERROR_BAD_FILE, |
| 663 | ERROR_BROKEN_STATE, | 663 | ERROR_BROKEN_STATE, |
| 664 | }; | 664 | }; |
| 665 | 665 | ||
| 666 | // Load file template | 666 | // Load file template |
| 667 | template<class T> | 667 | template<class T> |
| 668 | static Error Load(const std::string& _rFilename, int _Revision, const char *_VersionString, T& _class, std::string* _failureReason) | 668 | static Error Load(const std::string& _rFilename, int _Revision, const char *_VersionString, T& _class, std::string* _failureReason) |
| 669 | { | 669 | { |
| 670 | INFO_LOG(COMMON, "ChunkReader: Loading %s" , _rFilename.c_str()); | 670 | INFO_LOG(COMMON, "ChunkReader: Loading %s" , _rFilename.c_str()); |
| 671 | _failureReason->clear(); | 671 | _failureReason->clear(); |
| 672 | _failureReason->append("LoadStateWrongVersion"); | 672 | _failureReason->append("LoadStateWrongVersion"); |
| 673 | 673 | ||
| 674 | if (!File::Exists(_rFilename)) { | 674 | if (!File::Exists(_rFilename)) { |
| 675 | _failureReason->clear(); | 675 | _failureReason->clear(); |
| 676 | _failureReason->append("LoadStateDoesntExist"); | 676 | _failureReason->append("LoadStateDoesntExist"); |
| 677 | ERROR_LOG(COMMON, "ChunkReader: File doesn't exist"); | 677 | ERROR_LOG(COMMON, "ChunkReader: File doesn't exist"); |
| 678 | return ERROR_BAD_FILE; | 678 | return ERROR_BAD_FILE; |
| 679 | } | 679 | } |
| 680 | 680 | ||
| 681 | // Check file size | 681 | // Check file size |
| 682 | const u64 fileSize = File::GetSize(_rFilename); | 682 | const u64 fileSize = File::GetSize(_rFilename); |
| 683 | static const u64 headerSize = sizeof(SChunkHeader); | 683 | static const u64 headerSize = sizeof(SChunkHeader); |
| 684 | if (fileSize < headerSize) | 684 | if (fileSize < headerSize) |
| 685 | { | 685 | { |
| 686 | ERROR_LOG(COMMON,"ChunkReader: File too small"); | 686 | ERROR_LOG(COMMON,"ChunkReader: File too small"); |
| 687 | return ERROR_BAD_FILE; | 687 | return ERROR_BAD_FILE; |
| 688 | } | 688 | } |
| 689 | 689 | ||
| 690 | File::IOFile pFile(_rFilename, "rb"); | 690 | File::IOFile pFile(_rFilename, "rb"); |
| 691 | if (!pFile) | 691 | if (!pFile) |
| 692 | { | 692 | { |
| 693 | ERROR_LOG(COMMON,"ChunkReader: Can't open file for reading"); | 693 | ERROR_LOG(COMMON,"ChunkReader: Can't open file for reading"); |
| 694 | return ERROR_BAD_FILE; | 694 | return ERROR_BAD_FILE; |
| 695 | } | 695 | } |
| 696 | 696 | ||
| 697 | // read the header | 697 | // read the header |
| 698 | SChunkHeader header; | 698 | SChunkHeader header; |
| 699 | if (!pFile.ReadArray(&header, 1)) | 699 | if (!pFile.ReadArray(&header, 1)) |
| 700 | { | 700 | { |
| 701 | ERROR_LOG(COMMON,"ChunkReader: Bad header size"); | 701 | ERROR_LOG(COMMON,"ChunkReader: Bad header size"); |
| 702 | return ERROR_BAD_FILE; | 702 | return ERROR_BAD_FILE; |
| 703 | } | 703 | } |
| 704 | 704 | ||
| 705 | // Check revision | 705 | // Check revision |
| 706 | if (header.Revision != _Revision) | 706 | if (header.Revision != _Revision) |
| 707 | { | 707 | { |
| 708 | ERROR_LOG(COMMON,"ChunkReader: Wrong file revision, got %d expected %d", | 708 | ERROR_LOG(COMMON,"ChunkReader: Wrong file revision, got %d expected %d", |
| 709 | header.Revision, _Revision); | 709 | header.Revision, _Revision); |
| 710 | return ERROR_BAD_FILE; | 710 | return ERROR_BAD_FILE; |
| 711 | } | 711 | } |
| 712 | 712 | ||
| 713 | if (strcmp(header.GitVersion, _VersionString) != 0) | 713 | if (strcmp(header.GitVersion, _VersionString) != 0) |
| 714 | { | 714 | { |
| 715 | WARN_LOG(COMMON, "This savestate was generated by a different version of PPSSPP, %s. It may not load properly.", | 715 | WARN_LOG(COMMON, "This savestate was generated by a different version of PPSSPP, %s. It may not load properly.", |
| 716 | header.GitVersion); | 716 | header.GitVersion); |
| 717 | } | 717 | } |
| 718 | 718 | ||
| 719 | // get size | 719 | // get size |
| 720 | const int sz = (int)(fileSize - headerSize); | 720 | const int sz = (int)(fileSize - headerSize); |
| 721 | if (header.ExpectedSize != sz) | 721 | if (header.ExpectedSize != sz) |
| 722 | { | 722 | { |
| 723 | ERROR_LOG(COMMON,"ChunkReader: Bad file size, got %d expected %d", | 723 | ERROR_LOG(COMMON,"ChunkReader: Bad file size, got %d expected %d", |
| 724 | sz, header.ExpectedSize); | 724 | sz, header.ExpectedSize); |
| 725 | return ERROR_BAD_FILE; | 725 | return ERROR_BAD_FILE; |
| 726 | } | 726 | } |
| 727 | 727 | ||
| 728 | // read the state | 728 | // read the state |
| 729 | u8* buffer = new u8[sz]; | 729 | u8* buffer = new u8[sz]; |
| 730 | if (!pFile.ReadBytes(buffer, sz)) | 730 | if (!pFile.ReadBytes(buffer, sz)) |
| 731 | { | 731 | { |
| 732 | ERROR_LOG(COMMON,"ChunkReader: Error reading file"); | 732 | ERROR_LOG(COMMON,"ChunkReader: Error reading file"); |
| 733 | return ERROR_BAD_FILE; | 733 | return ERROR_BAD_FILE; |
| 734 | } | 734 | } |
| 735 | 735 | ||
| 736 | u8 *ptr = buffer; | 736 | u8 *ptr = buffer; |
| 737 | u8 *buf = buffer; | 737 | u8 *buf = buffer; |
| 738 | if (header.Compress) { | 738 | if (header.Compress) { |
| 739 | u8 *uncomp_buffer = new u8[header.UncompressedSize]; | 739 | u8 *uncomp_buffer = new u8[header.UncompressedSize]; |
| 740 | size_t uncomp_size = header.UncompressedSize; | 740 | size_t uncomp_size = header.UncompressedSize; |
| 741 | snappy_uncompress((const char *)buffer, sz, (char *)uncomp_buffer, &uncomp_size); | 741 | snappy_uncompress((const char *)buffer, sz, (char *)uncomp_buffer, &uncomp_size); |
| 742 | if ((int)uncomp_size != header.UncompressedSize) { | 742 | if ((int)uncomp_size != header.UncompressedSize) { |
| 743 | ERROR_LOG(COMMON,"Size mismatch: file: %i calc: %i", (int)header.UncompressedSize, (int)uncomp_size); | 743 | ERROR_LOG(COMMON,"Size mismatch: file: %i calc: %i", (int)header.UncompressedSize, (int)uncomp_size); |
| 744 | } | 744 | } |
| 745 | ptr = uncomp_buffer; | 745 | ptr = uncomp_buffer; |
| 746 | buf = uncomp_buffer; | 746 | buf = uncomp_buffer; |
| 747 | delete [] buffer; | 747 | delete [] buffer; |
| 748 | } | 748 | } |
| 749 | 749 | ||
| 750 | PointerWrap p(&ptr, PointerWrap::MODE_READ); | 750 | PointerWrap p(&ptr, PointerWrap::MODE_READ); |
| 751 | _class.DoState(p); | 751 | _class.DoState(p); |
| 752 | delete[] buf; | 752 | delete[] buf; |
| 753 | 753 | ||
| 754 | INFO_LOG(COMMON, "ChunkReader: Done loading %s" , _rFilename.c_str()); | 754 | INFO_LOG(COMMON, "ChunkReader: Done loading %s" , _rFilename.c_str()); |
| 755 | if (p.error != p.ERROR_FAILURE) { | 755 | if (p.error != p.ERROR_FAILURE) { |
| 756 | return ERROR_NONE; | 756 | return ERROR_NONE; |
| 757 | } else { | 757 | } else { |
| 758 | return ERROR_BROKEN_STATE; | 758 | return ERROR_BROKEN_STATE; |
| 759 | } | 759 | } |
| 760 | } | 760 | } |
| 761 | 761 | ||
| 762 | // Save file template | 762 | // Save file template |
| 763 | template<class T> | 763 | template<class T> |
| 764 | static Error Save(const std::string& _rFilename, int _Revision, const char *_VersionString, T& _class) | 764 | static Error Save(const std::string& _rFilename, int _Revision, const char *_VersionString, T& _class) |
| 765 | { | 765 | { |
| 766 | INFO_LOG(COMMON, "ChunkReader: Writing %s" , _rFilename.c_str()); | 766 | INFO_LOG(COMMON, "ChunkReader: Writing %s" , _rFilename.c_str()); |
| 767 | 767 | ||
| 768 | File::IOFile pFile(_rFilename, "wb"); | 768 | File::IOFile pFile(_rFilename, "wb"); |
| 769 | if (!pFile) | 769 | if (!pFile) |
| 770 | { | 770 | { |
| 771 | ERROR_LOG(COMMON,"ChunkReader: Error opening file for write"); | 771 | ERROR_LOG(COMMON,"ChunkReader: Error opening file for write"); |
| 772 | return ERROR_BAD_FILE; | 772 | return ERROR_BAD_FILE; |
| 773 | } | 773 | } |
| 774 | 774 | ||
| 775 | bool compress = true; | 775 | bool compress = true; |
| 776 | 776 | ||
| 777 | // Get data | 777 | // Get data |
| 778 | u8 *ptr = 0; | 778 | u8 *ptr = 0; |
| 779 | PointerWrap p(&ptr, PointerWrap::MODE_MEASURE); | 779 | PointerWrap p(&ptr, PointerWrap::MODE_MEASURE); |
| 780 | _class.DoState(p); | 780 | _class.DoState(p); |
| 781 | size_t const sz = (size_t)ptr; | 781 | size_t const sz = (size_t)ptr; |
| 782 | 782 | ||
| 783 | u8 * buffer = new u8[sz]; | 783 | u8 * buffer = new u8[sz]; |
| 784 | ptr = &buffer[0]; | 784 | ptr = &buffer[0]; |
| 785 | p.SetMode(PointerWrap::MODE_WRITE); | 785 | p.SetMode(PointerWrap::MODE_WRITE); |
| 786 | _class.DoState(p); | 786 | _class.DoState(p); |
| 787 | 787 | ||
| 788 | // Create header | 788 | // Create header |
| 789 | SChunkHeader header; | 789 | SChunkHeader header; |
| 790 | header.Compress = compress ? 1 : 0; | 790 | header.Compress = compress ? 1 : 0; |
| 791 | header.Revision = _Revision; | 791 | header.Revision = _Revision; |
| 792 | header.ExpectedSize = (int)sz; | 792 | header.ExpectedSize = (int)sz; |
| 793 | header.UncompressedSize = (int)sz; | 793 | header.UncompressedSize = (int)sz; |
| 794 | strncpy(header.GitVersion, _VersionString, 32); | 794 | strncpy(header.GitVersion, _VersionString, 32); |
| 795 | header.GitVersion[31] = '\0'; | 795 | header.GitVersion[31] = '\0'; |
| 796 | 796 | ||
| 797 | // Write to file | 797 | // Write to file |
| 798 | if (compress) { | 798 | if (compress) { |
| 799 | size_t comp_len = snappy_max_compressed_length(sz); | 799 | size_t comp_len = snappy_max_compressed_length(sz); |
| 800 | u8 *compressed_buffer = new u8[comp_len]; | 800 | u8 *compressed_buffer = new u8[comp_len]; |
| 801 | snappy_compress((const char *)buffer, sz, (char *)compressed_buffer, &comp_len); | 801 | snappy_compress((const char *)buffer, sz, (char *)compressed_buffer, &comp_len); |
| 802 | delete [] buffer; | 802 | delete [] buffer; |
| 803 | header.ExpectedSize = (int)comp_len; | 803 | header.ExpectedSize = (int)comp_len; |
| 804 | if (!pFile.WriteArray(&header, 1)) | 804 | if (!pFile.WriteArray(&header, 1)) |
| 805 | { | 805 | { |
| 806 | ERROR_LOG(COMMON,"ChunkReader: Failed writing header"); | 806 | ERROR_LOG(COMMON,"ChunkReader: Failed writing header"); |
| 807 | return ERROR_BAD_FILE; | 807 | return ERROR_BAD_FILE; |
| 808 | } | 808 | } |
| 809 | if (!pFile.WriteBytes(&compressed_buffer[0], comp_len)) { | 809 | if (!pFile.WriteBytes(&compressed_buffer[0], comp_len)) { |
| 810 | ERROR_LOG(COMMON,"ChunkReader: Failed writing compressed data"); | 810 | ERROR_LOG(COMMON,"ChunkReader: Failed writing compressed data"); |
| 811 | return ERROR_BAD_FILE; | 811 | return ERROR_BAD_FILE; |
| 812 | } else { | 812 | } else { |
| 813 | INFO_LOG(COMMON, "Savestate: Compressed %i bytes into %i", (int)sz, (int)comp_len); | 813 | INFO_LOG(COMMON, "Savestate: Compressed %i bytes into %i", (int)sz, (int)comp_len); |
| 814 | } | 814 | } |
| 815 | delete [] compressed_buffer; | 815 | delete [] compressed_buffer; |
| 816 | } else { | 816 | } else { |
| 817 | if (!pFile.WriteArray(&header, 1)) | 817 | if (!pFile.WriteArray(&header, 1)) |
| 818 | { | 818 | { |
| 819 | ERROR_LOG(COMMON,"ChunkReader: Failed writing header"); | 819 | ERROR_LOG(COMMON,"ChunkReader: Failed writing header"); |
| 820 | return ERROR_BAD_FILE; | 820 | return ERROR_BAD_FILE; |
| 821 | } | 821 | } |
| 822 | if (!pFile.WriteBytes(&buffer[0], sz)) | 822 | if (!pFile.WriteBytes(&buffer[0], sz)) |
| 823 | { | 823 | { |
| 824 | ERROR_LOG(COMMON,"ChunkReader: Failed writing data"); | 824 | ERROR_LOG(COMMON,"ChunkReader: Failed writing data"); |
| 825 | return ERROR_BAD_FILE; | 825 | return ERROR_BAD_FILE; |
| 826 | } | 826 | } |
| 827 | delete [] buffer; | 827 | delete [] buffer; |
| 828 | } | 828 | } |
| 829 | 829 | ||
| 830 | INFO_LOG(COMMON,"ChunkReader: Done writing %s", | 830 | INFO_LOG(COMMON,"ChunkReader: Done writing %s", |
| 831 | _rFilename.c_str()); | 831 | _rFilename.c_str()); |
| 832 | if (p.error != p.ERROR_FAILURE) { | 832 | if (p.error != p.ERROR_FAILURE) { |
| 833 | return ERROR_NONE; | 833 | return ERROR_NONE; |
| 834 | } else { | 834 | } else { |
| 835 | return ERROR_BROKEN_STATE; | 835 | return ERROR_BROKEN_STATE; |
| 836 | } | 836 | } |
| 837 | } | 837 | } |
| 838 | 838 | ||
| 839 | template <class T> | 839 | template <class T> |
| 840 | static Error Verify(T& _class) | 840 | static Error Verify(T& _class) |
| 841 | { | 841 | { |
| 842 | u8 *ptr = 0; | 842 | u8 *ptr = 0; |
| 843 | 843 | ||
| 844 | // Step 1: Measure the space required. | 844 | // Step 1: Measure the space required. |
| 845 | PointerWrap p(&ptr, PointerWrap::MODE_MEASURE); | 845 | PointerWrap p(&ptr, PointerWrap::MODE_MEASURE); |
| 846 | _class.DoState(p); | 846 | _class.DoState(p); |
| 847 | size_t const sz = (size_t)ptr; | 847 | size_t const sz = (size_t)ptr; |
| 848 | std::vector<u8> buffer(sz); | 848 | std::vector<u8> buffer(sz); |
| 849 | 849 | ||
| 850 | // Step 2: Dump the state. | 850 | // Step 2: Dump the state. |
| 851 | ptr = &buffer[0]; | 851 | ptr = &buffer[0]; |
| 852 | p.SetMode(PointerWrap::MODE_WRITE); | 852 | p.SetMode(PointerWrap::MODE_WRITE); |
| 853 | _class.DoState(p); | 853 | _class.DoState(p); |
| 854 | 854 | ||
| 855 | // Step 3: Verify the state. | 855 | // Step 3: Verify the state. |
| 856 | ptr = &buffer[0]; | 856 | ptr = &buffer[0]; |
| 857 | p.SetMode(PointerWrap::MODE_VERIFY); | 857 | p.SetMode(PointerWrap::MODE_VERIFY); |
| 858 | _class.DoState(p); | 858 | _class.DoState(p); |
| 859 | 859 | ||
| 860 | return ERROR_NONE; | 860 | return ERROR_NONE; |
| 861 | } | 861 | } |
| 862 | 862 | ||
| 863 | private: | 863 | private: |
| 864 | struct SChunkHeader | 864 | struct SChunkHeader |
| 865 | { | 865 | { |
| 866 | int Revision; | 866 | int Revision; |
| 867 | int Compress; | 867 | int Compress; |
| 868 | int ExpectedSize; | 868 | int ExpectedSize; |
| 869 | int UncompressedSize; | 869 | int UncompressedSize; |
| 870 | char GitVersion[32]; | 870 | char GitVersion[32]; |
| 871 | }; | 871 | }; |
| 872 | }; | 872 | }; |
| 873 | 873 | ||
| 874 | #endif // _POINTERWRAP_H_ | 874 | #endif // _POINTERWRAP_H_ |
diff --git a/src/common/src/common.h b/src/common/src/common.h index 0f2c34727..1ca34e467 100644 --- a/src/common/src/common.h +++ b/src/common/src/common.h | |||
| @@ -34,12 +34,12 @@ extern const char *netplay_dolphin_ver; | |||
| 34 | class NonCopyable | 34 | class NonCopyable |
| 35 | { | 35 | { |
| 36 | protected: | 36 | protected: |
| 37 | NonCopyable() {} | 37 | NonCopyable() {} |
| 38 | NonCopyable(const NonCopyable&&) {} | 38 | NonCopyable(const NonCopyable&&) {} |
| 39 | void operator=(const NonCopyable&&) {} | 39 | void operator=(const NonCopyable&&) {} |
| 40 | private: | 40 | private: |
| 41 | NonCopyable(NonCopyable&); | 41 | NonCopyable(NonCopyable&); |
| 42 | NonCopyable& operator=(NonCopyable& other); | 42 | NonCopyable& operator=(NonCopyable& other); |
| 43 | }; | 43 | }; |
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| @@ -61,40 +61,40 @@ private: | |||
| 61 | #elif defined _WIN32 | 61 | #elif defined _WIN32 |
| 62 | 62 | ||
| 63 | // Check MSC ver | 63 | // Check MSC ver |
| 64 | #if !defined _MSC_VER || _MSC_VER <= 1000 | 64 | #if !defined _MSC_VER || _MSC_VER <= 1000 |
| 65 | #error needs at least version 1000 of MSC | 65 | #error needs at least version 1000 of MSC |
| 66 | #endif | 66 | #endif |
| 67 | 67 | ||
| 68 | #define NOMINMAX | 68 | #define NOMINMAX |
| 69 | 69 | ||
| 70 | // Memory leak checks | 70 | // Memory leak checks |
| 71 | #define CHECK_HEAP_INTEGRITY() | 71 | #define CHECK_HEAP_INTEGRITY() |
| 72 | 72 | ||
| 73 | // Alignment | 73 | // Alignment |
| 74 | #define MEMORY_ALIGNED16(x) __declspec(align(16)) x | 74 | #define MEMORY_ALIGNED16(x) __declspec(align(16)) x |
| 75 | #define MEMORY_ALIGNED32(x) __declspec(align(32)) x | 75 | #define MEMORY_ALIGNED32(x) __declspec(align(32)) x |
| 76 | #define MEMORY_ALIGNED64(x) __declspec(align(64)) x | 76 | #define MEMORY_ALIGNED64(x) __declspec(align(64)) x |
| 77 | #define MEMORY_ALIGNED128(x) __declspec(align(128)) x | 77 | #define MEMORY_ALIGNED128(x) __declspec(align(128)) x |
| 78 | #define MEMORY_ALIGNED16_DECL(x) __declspec(align(16)) x | 78 | #define MEMORY_ALIGNED16_DECL(x) __declspec(align(16)) x |
| 79 | #define MEMORY_ALIGNED64_DECL(x) __declspec(align(64)) x | 79 | #define MEMORY_ALIGNED64_DECL(x) __declspec(align(64)) x |
| 80 | 80 | ||
| 81 | // Since they are always around on windows | 81 | // Since they are always around on windows |
| 82 | #define HAVE_WX 1 | 82 | #define HAVE_WX 1 |
| 83 | #define HAVE_OPENAL 1 | 83 | #define HAVE_OPENAL 1 |
| 84 | 84 | ||
| 85 | #define HAVE_PORTAUDIO 1 | 85 | #define HAVE_PORTAUDIO 1 |
| 86 | 86 | ||
| 87 | // Debug definitions | 87 | // Debug definitions |
| 88 | #if defined(_DEBUG) | 88 | #if defined(_DEBUG) |
| 89 | #include <crtdbg.h> | 89 | #include <crtdbg.h> |
| 90 | #undef CHECK_HEAP_INTEGRITY | 90 | #undef CHECK_HEAP_INTEGRITY |
| 91 | #define CHECK_HEAP_INTEGRITY() {if (!_CrtCheckMemory()) PanicAlert("memory corruption detected. see log.");} | 91 | #define CHECK_HEAP_INTEGRITY() {if (!_CrtCheckMemory()) PanicAlert("memory corruption detected. see log.");} |
| 92 | // If you want to see how much a pain in the ass singletons are, for example: | 92 | // If you want to see how much a pain in the ass singletons are, for example: |
| 93 | // {614} normal block at 0x030C5310, 188 bytes long. | 93 | // {614} normal block at 0x030C5310, 188 bytes long. |
| 94 | // Data: <Master Log > 4D 61 73 74 65 72 20 4C 6F 67 00 00 00 00 00 00 | 94 | // Data: <Master Log > 4D 61 73 74 65 72 20 4C 6F 67 00 00 00 00 00 00 |
| 95 | struct CrtDebugBreak { CrtDebugBreak(int spot) { _CrtSetBreakAlloc(spot); } }; | 95 | struct CrtDebugBreak { CrtDebugBreak(int spot) { _CrtSetBreakAlloc(spot); } }; |
| 96 | //CrtDebugBreak breakAt(614); | 96 | //CrtDebugBreak breakAt(614); |
| 97 | #endif // end DEBUG/FAST | 97 | #endif // end DEBUG/FAST |
| 98 | 98 | ||
| 99 | #endif | 99 | #endif |
| 100 | 100 | ||
| @@ -149,18 +149,18 @@ private: | |||
| 149 | // Host communication. | 149 | // Host communication. |
| 150 | enum HOST_COMM | 150 | enum HOST_COMM |
| 151 | { | 151 | { |
| 152 | // Begin at 10 in case there is already messages with wParam = 0, 1, 2 and so on | 152 | // Begin at 10 in case there is already messages with wParam = 0, 1, 2 and so on |
| 153 | WM_USER_STOP = 10, | 153 | WM_USER_STOP = 10, |
| 154 | WM_USER_CREATE, | 154 | WM_USER_CREATE, |
| 155 | WM_USER_SETCURSOR, | 155 | WM_USER_SETCURSOR, |
| 156 | }; | 156 | }; |
| 157 | 157 | ||
| 158 | // Used for notification on emulation state | 158 | // Used for notification on emulation state |
| 159 | enum EMUSTATE_CHANGE | 159 | enum EMUSTATE_CHANGE |
| 160 | { | 160 | { |
| 161 | EMUSTATE_CHANGE_PLAY = 1, | 161 | EMUSTATE_CHANGE_PLAY = 1, |
| 162 | EMUSTATE_CHANGE_PAUSE, | 162 | EMUSTATE_CHANGE_PAUSE, |
| 163 | EMUSTATE_CHANGE_STOP | 163 | EMUSTATE_CHANGE_STOP |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | #endif // _COMMON_H_ | 166 | #endif // _COMMON_H_ |
diff --git a/src/common/src/common_funcs.h b/src/common/src/common_funcs.h index 9fa44c894..7ca0b3501 100644 --- a/src/common/src/common_funcs.h +++ b/src/common/src/common_funcs.h | |||
| @@ -20,7 +20,7 @@ template<> struct CompileTimeAssert<true> {}; | |||
| 20 | #define b8(x) ( b4(x) | ( b4(x) >> 4) ) | 20 | #define b8(x) ( b4(x) | ( b4(x) >> 4) ) |
| 21 | #define b16(x) ( b8(x) | ( b8(x) >> 8) ) | 21 | #define b16(x) ( b8(x) | ( b8(x) >> 8) ) |
| 22 | #define b32(x) (b16(x) | (b16(x) >>16) ) | 22 | #define b32(x) (b16(x) | (b16(x) >>16) ) |
| 23 | #define ROUND_UP_POW2(x) (b32(x - 1) + 1) | 23 | #define ROUND_UP_POW2(x) (b32(x - 1) + 1) |
| 24 | 24 | ||
| 25 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) | 25 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) |
| 26 | 26 | ||
| @@ -29,11 +29,11 @@ template<> struct CompileTimeAssert<true> {}; | |||
| 29 | static __inline __m128i __attribute__((__always_inline__)) | 29 | static __inline __m128i __attribute__((__always_inline__)) |
| 30 | _mm_shuffle_epi8(__m128i a, __m128i mask) | 30 | _mm_shuffle_epi8(__m128i a, __m128i mask) |
| 31 | { | 31 | { |
| 32 | __m128i result; | 32 | __m128i result; |
| 33 | __asm__("pshufb %1, %0" | 33 | __asm__("pshufb %1, %0" |
| 34 | : "=x" (result) | 34 | : "=x" (result) |
| 35 | : "xm" (mask), "0" (a)); | 35 | : "xm" (mask), "0" (a)); |
| 36 | return result; | 36 | return result; |
| 37 | } | 37 | } |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| @@ -47,103 +47,103 @@ _mm_shuffle_epi8(__m128i a, __m128i mask) | |||
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | // go to debugger mode | 49 | // go to debugger mode |
| 50 | #ifdef GEKKO | 50 | #ifdef GEKKO |
| 51 | #define Crash() | 51 | #define Crash() |
| 52 | #elif defined _M_GENERIC | 52 | #elif defined _M_GENERIC |
| 53 | #define Crash() { exit(1); } | 53 | #define Crash() { exit(1); } |
| 54 | #else | 54 | #else |
| 55 | #define Crash() {asm ("int $3");} | 55 | #define Crash() {asm ("int $3");} |
| 56 | #endif | 56 | #endif |
| 57 | #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) | 57 | #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) |
| 58 | // GCC 4.8 defines all the rotate functions now | 58 | // GCC 4.8 defines all the rotate functions now |
| 59 | // Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit | 59 | // Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit |
| 60 | #ifndef _rotl | 60 | #ifndef _rotl |
| 61 | inline u32 _rotl(u32 x, int shift) { | 61 | inline u32 _rotl(u32 x, int shift) { |
| 62 | shift &= 31; | 62 | shift &= 31; |
| 63 | if (!shift) return x; | 63 | if (!shift) return x; |
| 64 | return (x << shift) | (x >> (32 - shift)); | 64 | return (x << shift) | (x >> (32 - shift)); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | inline u32 _rotr(u32 x, int shift) { | 67 | inline u32 _rotr(u32 x, int shift) { |
| 68 | shift &= 31; | 68 | shift &= 31; |
| 69 | if (!shift) return x; | 69 | if (!shift) return x; |
| 70 | return (x >> shift) | (x << (32 - shift)); | 70 | return (x >> shift) | (x << (32 - shift)); |
| 71 | } | 71 | } |
| 72 | #endif | 72 | #endif |
| 73 | 73 | ||
| 74 | inline u64 _rotl64(u64 x, unsigned int shift){ | 74 | inline u64 _rotl64(u64 x, unsigned int shift){ |
| 75 | unsigned int n = shift % 64; | 75 | unsigned int n = shift % 64; |
| 76 | return (x << n) | (x >> (64 - n)); | 76 | return (x << n) | (x >> (64 - n)); |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | inline u64 _rotr64(u64 x, unsigned int shift){ | 79 | inline u64 _rotr64(u64 x, unsigned int shift){ |
| 80 | unsigned int n = shift % 64; | 80 | unsigned int n = shift % 64; |
| 81 | return (x >> n) | (x << (64 - n)); | 81 | return (x >> n) | (x << (64 - n)); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | #else // WIN32 | 84 | #else // WIN32 |
| 85 | // Function Cross-Compatibility | 85 | // Function Cross-Compatibility |
| 86 | #define strcasecmp _stricmp | 86 | #define strcasecmp _stricmp |
| 87 | #define strncasecmp _strnicmp | 87 | #define strncasecmp _strnicmp |
| 88 | #define unlink _unlink | 88 | #define unlink _unlink |
| 89 | #define snprintf _snprintf | 89 | #define snprintf _snprintf |
| 90 | #define vscprintf _vscprintf | 90 | #define vscprintf _vscprintf |
| 91 | 91 | ||
| 92 | // Locale Cross-Compatibility | 92 | // Locale Cross-Compatibility |
| 93 | #define locale_t _locale_t | 93 | #define locale_t _locale_t |
| 94 | #define freelocale _free_locale | 94 | #define freelocale _free_locale |
| 95 | #define newlocale(mask, locale, base) _create_locale(mask, locale) | 95 | #define newlocale(mask, locale, base) _create_locale(mask, locale) |
| 96 | 96 | ||
| 97 | #define LC_GLOBAL_LOCALE ((locale_t)-1) | 97 | #define LC_GLOBAL_LOCALE ((locale_t)-1) |
| 98 | #define LC_ALL_MASK LC_ALL | 98 | #define LC_ALL_MASK LC_ALL |
| 99 | #define LC_COLLATE_MASK LC_COLLATE | 99 | #define LC_COLLATE_MASK LC_COLLATE |
| 100 | #define LC_CTYPE_MASK LC_CTYPE | 100 | #define LC_CTYPE_MASK LC_CTYPE |
| 101 | #define LC_MONETARY_MASK LC_MONETARY | 101 | #define LC_MONETARY_MASK LC_MONETARY |
| 102 | #define LC_NUMERIC_MASK LC_NUMERIC | 102 | #define LC_NUMERIC_MASK LC_NUMERIC |
| 103 | #define LC_TIME_MASK LC_TIME | 103 | #define LC_TIME_MASK LC_TIME |
| 104 | 104 | ||
| 105 | inline locale_t uselocale(locale_t new_locale) | 105 | inline locale_t uselocale(locale_t new_locale) |
| 106 | { | 106 | { |
| 107 | // Retrieve the current per thread locale setting | 107 | // Retrieve the current per thread locale setting |
| 108 | bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE); | 108 | bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE); |
| 109 | 109 | ||
| 110 | // Retrieve the current thread-specific locale | 110 | // Retrieve the current thread-specific locale |
| 111 | locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE; | 111 | locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE; |
| 112 | 112 | ||
| 113 | if(new_locale == LC_GLOBAL_LOCALE) | 113 | if(new_locale == LC_GLOBAL_LOCALE) |
| 114 | { | 114 | { |
| 115 | // Restore the global locale | 115 | // Restore the global locale |
| 116 | _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); | 116 | _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); |
| 117 | } | 117 | } |
| 118 | else if(new_locale != NULL) | 118 | else if(new_locale != NULL) |
| 119 | { | 119 | { |
| 120 | // Configure the thread to set the locale only for this thread | 120 | // Configure the thread to set the locale only for this thread |
| 121 | _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); | 121 | _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); |
| 122 | 122 | ||
| 123 | // Set all locale categories | 123 | // Set all locale categories |
| 124 | for(int i = LC_MIN; i <= LC_MAX; i++) | 124 | for(int i = LC_MIN; i <= LC_MAX; i++) |
| 125 | setlocale(i, new_locale->locinfo->lc_category[i].locale); | 125 | setlocale(i, new_locale->locinfo->lc_category[i].locale); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | return old_locale; | 128 | return old_locale; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | // 64 bit offsets for windows | 131 | // 64 bit offsets for windows |
| 132 | #define fseeko _fseeki64 | 132 | #define fseeko _fseeki64 |
| 133 | #define ftello _ftelli64 | 133 | #define ftello _ftelli64 |
| 134 | #define atoll _atoi64 | 134 | #define atoll _atoi64 |
| 135 | #define stat64 _stat64 | 135 | #define stat64 _stat64 |
| 136 | #define fstat64 _fstat64 | 136 | #define fstat64 _fstat64 |
| 137 | #define fileno _fileno | 137 | #define fileno _fileno |
| 138 | 138 | ||
| 139 | #if _M_IX86 | 139 | #if _M_IX86 |
| 140 | #define Crash() {__asm int 3} | 140 | #define Crash() {__asm int 3} |
| 141 | #else | 141 | #else |
| 142 | extern "C" { | 142 | extern "C" { |
| 143 | __declspec(dllimport) void __stdcall DebugBreak(void); | 143 | __declspec(dllimport) void __stdcall DebugBreak(void); |
| 144 | } | 144 | } |
| 145 | #define Crash() {DebugBreak();} | 145 | #define Crash() {DebugBreak();} |
| 146 | #endif // M_IX86 | 146 | #endif // M_IX86 |
| 147 | #endif // WIN32 ndef | 147 | #endif // WIN32 ndef |
| 148 | 148 | ||
| 149 | // Dolphin's min and max functions | 149 | // Dolphin's min and max functions |
| @@ -186,11 +186,11 @@ inline u32 swap32(u32 _data) {return bswap_32(_data);} | |||
| 186 | inline u64 swap64(u64 _data) {return bswap_64(_data);} | 186 | inline u64 swap64(u64 _data) {return bswap_64(_data);} |
| 187 | #elif __APPLE__ | 187 | #elif __APPLE__ |
| 188 | inline __attribute__((always_inline)) u16 swap16(u16 _data) | 188 | inline __attribute__((always_inline)) u16 swap16(u16 _data) |
| 189 | {return (_data >> 8) | (_data << 8);} | 189 | {return (_data >> 8) | (_data << 8);} |
| 190 | inline __attribute__((always_inline)) u32 swap32(u32 _data) | 190 | inline __attribute__((always_inline)) u32 swap32(u32 _data) |
| 191 | {return __builtin_bswap32(_data);} | 191 | {return __builtin_bswap32(_data);} |
| 192 | inline __attribute__((always_inline)) u64 swap64(u64 _data) | 192 | inline __attribute__((always_inline)) u64 swap64(u64 _data) |
| 193 | {return __builtin_bswap64(_data);} | 193 | {return __builtin_bswap64(_data);} |
| 194 | #elif __FreeBSD__ | 194 | #elif __FreeBSD__ |
| 195 | inline u16 swap16(u16 _data) {return bswap16(_data);} | 195 | inline u16 swap16(u16 _data) {return bswap16(_data);} |
| 196 | inline u32 swap32(u32 _data) {return bswap32(_data);} | 196 | inline u32 swap32(u32 _data) {return bswap32(_data);} |
| @@ -216,28 +216,28 @@ inline void swap<1>(u8* data) | |||
| 216 | template <> | 216 | template <> |
| 217 | inline void swap<2>(u8* data) | 217 | inline void swap<2>(u8* data) |
| 218 | { | 218 | { |
| 219 | *reinterpret_cast<u16*>(data) = swap16(data); | 219 | *reinterpret_cast<u16*>(data) = swap16(data); |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | template <> | 222 | template <> |
| 223 | inline void swap<4>(u8* data) | 223 | inline void swap<4>(u8* data) |
| 224 | { | 224 | { |
| 225 | *reinterpret_cast<u32*>(data) = swap32(data); | 225 | *reinterpret_cast<u32*>(data) = swap32(data); |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | template <> | 228 | template <> |
| 229 | inline void swap<8>(u8* data) | 229 | inline void swap<8>(u8* data) |
| 230 | { | 230 | { |
| 231 | *reinterpret_cast<u64*>(data) = swap64(data); | 231 | *reinterpret_cast<u64*>(data) = swap64(data); |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | template <typename T> | 234 | template <typename T> |
| 235 | inline T FromBigEndian(T data) | 235 | inline T FromBigEndian(T data) |
| 236 | { | 236 | { |
| 237 | //static_assert(std::is_arithmetic<T>::value, "function only makes sense with arithmetic types"); | 237 | //static_assert(std::is_arithmetic<T>::value, "function only makes sense with arithmetic types"); |
| 238 | 238 | ||
| 239 | swap<sizeof(data)>(reinterpret_cast<u8*>(&data)); | 239 | swap<sizeof(data)>(reinterpret_cast<u8*>(&data)); |
| 240 | return data; | 240 | return data; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | } // Namespace Common | 243 | } // Namespace Common |
diff --git a/src/common/src/common_paths.h b/src/common/src/common_paths.h index 30bd4b742..9ccb87d82 100644 --- a/src/common/src/common_paths.h +++ b/src/common/src/common_paths.h | |||
| @@ -13,34 +13,34 @@ | |||
| 13 | #define DIR_SEP_CHR '/' | 13 | #define DIR_SEP_CHR '/' |
| 14 | 14 | ||
| 15 | #ifndef MAX_PATH | 15 | #ifndef MAX_PATH |
| 16 | #define MAX_PATH 260 | 16 | #define MAX_PATH 260 |
| 17 | #endif | 17 | #endif |
| 18 | 18 | ||
| 19 | // The user data dir | 19 | // The user data dir |
| 20 | #define ROOT_DIR "." | 20 | #define ROOT_DIR "." |
| 21 | #ifdef _WIN32 | 21 | #ifdef _WIN32 |
| 22 | #define USERDATA_DIR "user" | 22 | #define USERDATA_DIR "user" |
| 23 | #define EMU_DATA_DIR "emu" | 23 | #define EMU_DATA_DIR "emu" |
| 24 | #else | 24 | #else |
| 25 | #define USERDATA_DIR "user" | 25 | #define USERDATA_DIR "user" |
| 26 | #ifdef USER_DIR | 26 | #ifdef USER_DIR |
| 27 | #define EMU_DATA_DIR USER_DIR | 27 | #define EMU_DATA_DIR USER_DIR |
| 28 | #else | 28 | #else |
| 29 | #define EMU_DATA_DIR ".emu" | 29 | #define EMU_DATA_DIR ".emu" |
| 30 | #endif | 30 | #endif |
| 31 | #endif | 31 | #endif |
| 32 | 32 | ||
| 33 | // Shared data dirs (Sys and shared User for linux) | 33 | // Shared data dirs (Sys and shared User for linux) |
| 34 | #ifdef _WIN32 | 34 | #ifdef _WIN32 |
| 35 | #define SYSDATA_DIR "sys" | 35 | #define SYSDATA_DIR "sys" |
| 36 | #else | 36 | #else |
| 37 | #ifdef DATA_DIR | 37 | #ifdef DATA_DIR |
| 38 | #define SYSDATA_DIR DATA_DIR "sys" | 38 | #define SYSDATA_DIR DATA_DIR "sys" |
| 39 | #define SHARED_USER_DIR DATA_DIR USERDATA_DIR DIR_SEP | 39 | #define SHARED_USER_DIR DATA_DIR USERDATA_DIR DIR_SEP |
| 40 | #else | 40 | #else |
| 41 | #define SYSDATA_DIR "sys" | 41 | #define SYSDATA_DIR "sys" |
| 42 | #define SHARED_USER_DIR ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP | 42 | #define SHARED_USER_DIR ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP |
| 43 | #endif | 43 | #endif |
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | // Dirs in both User and Sys | 46 | // Dirs in both User and Sys |
| @@ -49,31 +49,31 @@ | |||
| 49 | #define JAP_DIR "JAP" | 49 | #define JAP_DIR "JAP" |
| 50 | 50 | ||
| 51 | // Subdirs in the User dir returned by GetUserPath(D_USER_IDX) | 51 | // Subdirs in the User dir returned by GetUserPath(D_USER_IDX) |
| 52 | #define CONFIG_DIR "config" | 52 | #define CONFIG_DIR "config" |
| 53 | #define GAMECONFIG_DIR "game_config" | 53 | #define GAMECONFIG_DIR "game_config" |
| 54 | #define MAPS_DIR "maps" | 54 | #define MAPS_DIR "maps" |
| 55 | #define CACHE_DIR "cache" | 55 | #define CACHE_DIR "cache" |
| 56 | #define SHADERCACHE_DIR "shader_cache" | 56 | #define SHADERCACHE_DIR "shader_cache" |
| 57 | #define STATESAVES_DIR "state_saves" | 57 | #define STATESAVES_DIR "state_saves" |
| 58 | #define SCREENSHOTS_DIR "screenShots" | 58 | #define SCREENSHOTS_DIR "screenShots" |
| 59 | #define DUMP_DIR "dump" | 59 | #define DUMP_DIR "dump" |
| 60 | #define DUMP_TEXTURES_DIR "textures" | 60 | #define DUMP_TEXTURES_DIR "textures" |
| 61 | #define DUMP_FRAMES_DIR "frames" | 61 | #define DUMP_FRAMES_DIR "frames" |
| 62 | #define DUMP_AUDIO_DIR "audio" | 62 | #define DUMP_AUDIO_DIR "audio" |
| 63 | #define LOGS_DIR "logs" | 63 | #define LOGS_DIR "logs" |
| 64 | #define SHADERS_DIR "shaders" | 64 | #define SHADERS_DIR "shaders" |
| 65 | #define SYSCONF_DIR "sysconf" | 65 | #define SYSCONF_DIR "sysconf" |
| 66 | 66 | ||
| 67 | // Filenames | 67 | // Filenames |
| 68 | // Files in the directory returned by GetUserPath(D_CONFIG_IDX) | 68 | // Files in the directory returned by GetUserPath(D_CONFIG_IDX) |
| 69 | #define EMU_CONFIG "emu.ini" | 69 | #define EMU_CONFIG "emu.ini" |
| 70 | #define DEBUGGER_CONFIG "debugger.ini" | 70 | #define DEBUGGER_CONFIG "debugger.ini" |
| 71 | #define LOGGER_CONFIG "logger.ini" | 71 | #define LOGGER_CONFIG "logger.ini" |
| 72 | 72 | ||
| 73 | // Files in the directory returned by GetUserPath(D_LOGS_IDX) | 73 | // Files in the directory returned by GetUserPath(D_LOGS_IDX) |
| 74 | #define MAIN_LOG "emu.log" | 74 | #define MAIN_LOG "emu.log" |
| 75 | 75 | ||
| 76 | // Files in the directory returned by GetUserPath(D_SYSCONF_IDX) | 76 | // Files in the directory returned by GetUserPath(D_SYSCONF_IDX) |
| 77 | #define SYSCONF "SYSCONF" | 77 | #define SYSCONF "SYSCONF" |
| 78 | 78 | ||
| 79 | #endif // _COMMON_PATHS_H_ | 79 | #endif // _COMMON_PATHS_H_ |
diff --git a/src/common/src/console_listener.cpp b/src/common/src/console_listener.cpp index 84f57675d..270ad9ce9 100644 --- a/src/common/src/console_listener.cpp +++ b/src/common/src/console_listener.cpp | |||
| @@ -20,16 +20,16 @@ | |||
| 20 | ConsoleListener::ConsoleListener() | 20 | ConsoleListener::ConsoleListener() |
| 21 | { | 21 | { |
| 22 | #ifdef _WIN32 | 22 | #ifdef _WIN32 |
| 23 | hConsole = NULL; | 23 | hConsole = NULL; |
| 24 | bUseColor = true; | 24 | bUseColor = true; |
| 25 | #else | 25 | #else |
| 26 | bUseColor = isatty(fileno(stdout)); | 26 | bUseColor = isatty(fileno(stdout)); |
| 27 | #endif | 27 | #endif |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | ConsoleListener::~ConsoleListener() | 30 | ConsoleListener::~ConsoleListener() |
| 31 | { | 31 | { |
| 32 | Close(); | 32 | Close(); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | // 100, 100, "Dolphin Log Console" | 35 | // 100, 100, "Dolphin Log Console" |
| @@ -38,31 +38,31 @@ ConsoleListener::~ConsoleListener() | |||
| 38 | void ConsoleListener::Open(bool Hidden, int Width, int Height, const char *Title) | 38 | void ConsoleListener::Open(bool Hidden, int Width, int Height, const char *Title) |
| 39 | { | 39 | { |
| 40 | #ifdef _WIN32 | 40 | #ifdef _WIN32 |
| 41 | if (!GetConsoleWindow()) | 41 | if (!GetConsoleWindow()) |
| 42 | { | 42 | { |
| 43 | // Open the console window and create the window handle for GetStdHandle() | 43 | // Open the console window and create the window handle for GetStdHandle() |
| 44 | AllocConsole(); | 44 | AllocConsole(); |
| 45 | // Hide | 45 | // Hide |
| 46 | if (Hidden) ShowWindow(GetConsoleWindow(), SW_HIDE); | 46 | if (Hidden) ShowWindow(GetConsoleWindow(), SW_HIDE); |
| 47 | // Save the window handle that AllocConsole() created | 47 | // Save the window handle that AllocConsole() created |
| 48 | hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | 48 | hConsole = GetStdHandle(STD_OUTPUT_HANDLE); |
| 49 | // Set the console window title | 49 | // Set the console window title |
| 50 | SetConsoleTitle(UTF8ToTStr(Title).c_str()); | 50 | SetConsoleTitle(UTF8ToTStr(Title).c_str()); |
| 51 | // Set letter space | 51 | // Set letter space |
| 52 | LetterSpace(80, 4000); | 52 | LetterSpace(80, 4000); |
| 53 | //MoveWindow(GetConsoleWindow(), 200,200, 800,800, true); | 53 | //MoveWindow(GetConsoleWindow(), 200,200, 800,800, true); |
| 54 | } | 54 | } |
| 55 | else | 55 | else |
| 56 | { | 56 | { |
| 57 | hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | 57 | hConsole = GetStdHandle(STD_OUTPUT_HANDLE); |
| 58 | } | 58 | } |
| 59 | #endif | 59 | #endif |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | void ConsoleListener::UpdateHandle() | 62 | void ConsoleListener::UpdateHandle() |
| 63 | { | 63 | { |
| 64 | #ifdef _WIN32 | 64 | #ifdef _WIN32 |
| 65 | hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | 65 | hConsole = GetStdHandle(STD_OUTPUT_HANDLE); |
| 66 | #endif | 66 | #endif |
| 67 | } | 67 | } |
| 68 | 68 | ||
| @@ -70,267 +70,267 @@ void ConsoleListener::UpdateHandle() | |||
| 70 | void ConsoleListener::Close() | 70 | void ConsoleListener::Close() |
| 71 | { | 71 | { |
| 72 | #ifdef _WIN32 | 72 | #ifdef _WIN32 |
| 73 | if (hConsole == NULL) | 73 | if (hConsole == NULL) |
| 74 | return; | 74 | return; |
| 75 | FreeConsole(); | 75 | FreeConsole(); |
| 76 | hConsole = NULL; | 76 | hConsole = NULL; |
| 77 | #else | 77 | #else |
| 78 | fflush(NULL); | 78 | fflush(NULL); |
| 79 | #endif | 79 | #endif |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | bool ConsoleListener::IsOpen() | 82 | bool ConsoleListener::IsOpen() |
| 83 | { | 83 | { |
| 84 | #ifdef _WIN32 | 84 | #ifdef _WIN32 |
| 85 | return (hConsole != NULL); | 85 | return (hConsole != NULL); |
| 86 | #else | 86 | #else |
| 87 | return true; | 87 | return true; |
| 88 | #endif | 88 | #endif |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | /* | 91 | /* |
| 92 | LetterSpace: SetConsoleScreenBufferSize and SetConsoleWindowInfo are | 92 | LetterSpace: SetConsoleScreenBufferSize and SetConsoleWindowInfo are |
| 93 | dependent on each other, that's the reason for the additional checks. | 93 | dependent on each other, that's the reason for the additional checks. |
| 94 | */ | 94 | */ |
| 95 | void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst) | 95 | void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst) |
| 96 | { | 96 | { |
| 97 | #ifdef _WIN32 | 97 | #ifdef _WIN32 |
| 98 | BOOL SB, SW; | 98 | BOOL SB, SW; |
| 99 | if (BufferFirst) | 99 | if (BufferFirst) |
| 100 | { | 100 | { |
| 101 | // Change screen buffer size | 101 | // Change screen buffer size |
| 102 | COORD Co = {BufferWidth, BufferHeight}; | 102 | COORD Co = {BufferWidth, BufferHeight}; |
| 103 | SB = SetConsoleScreenBufferSize(hConsole, Co); | 103 | SB = SetConsoleScreenBufferSize(hConsole, Co); |
| 104 | // Change the screen buffer window size | 104 | // Change the screen buffer window size |
| 105 | SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom | 105 | SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom |
| 106 | SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); | 106 | SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); |
| 107 | } | 107 | } |
| 108 | else | 108 | else |
| 109 | { | 109 | { |
| 110 | // Change the screen buffer window size | 110 | // Change the screen buffer window size |
| 111 | SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom | 111 | SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom |
| 112 | SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); | 112 | SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); |
| 113 | // Change screen buffer size | 113 | // Change screen buffer size |
| 114 | COORD Co = {BufferWidth, BufferHeight}; | 114 | COORD Co = {BufferWidth, BufferHeight}; |
| 115 | SB = SetConsoleScreenBufferSize(hConsole, Co); | 115 | SB = SetConsoleScreenBufferSize(hConsole, Co); |
| 116 | } | 116 | } |
| 117 | #endif | 117 | #endif |
| 118 | } | 118 | } |
| 119 | void ConsoleListener::LetterSpace(int Width, int Height) | 119 | void ConsoleListener::LetterSpace(int Width, int Height) |
| 120 | { | 120 | { |
| 121 | #ifdef _WIN32 | 121 | #ifdef _WIN32 |
| 122 | // Get console info | 122 | // Get console info |
| 123 | CONSOLE_SCREEN_BUFFER_INFO ConInfo; | 123 | CONSOLE_SCREEN_BUFFER_INFO ConInfo; |
| 124 | GetConsoleScreenBufferInfo(hConsole, &ConInfo); | 124 | GetConsoleScreenBufferInfo(hConsole, &ConInfo); |
| 125 | 125 | ||
| 126 | // | 126 | // |
| 127 | int OldBufferWidth = ConInfo.dwSize.X; | 127 | int OldBufferWidth = ConInfo.dwSize.X; |
| 128 | int OldBufferHeight = ConInfo.dwSize.Y; | 128 | int OldBufferHeight = ConInfo.dwSize.Y; |
| 129 | int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left); | 129 | int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left); |
| 130 | int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top); | 130 | int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top); |
| 131 | // | 131 | // |
| 132 | int NewBufferWidth = Width; | 132 | int NewBufferWidth = Width; |
| 133 | int NewBufferHeight = Height; | 133 | int NewBufferHeight = Height; |
| 134 | int NewScreenWidth = NewBufferWidth - 1; | 134 | int NewScreenWidth = NewBufferWidth - 1; |
| 135 | int NewScreenHeight = OldScreenHeight; | 135 | int NewScreenHeight = OldScreenHeight; |
| 136 | 136 | ||
| 137 | // Width | 137 | // Width |
| 138 | BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1)); | 138 | BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1)); |
| 139 | // Height | 139 | // Height |
| 140 | BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1)); | 140 | BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1)); |
| 141 | 141 | ||
| 142 | // Resize the window too | 142 | // Resize the window too |
| 143 | //MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true); | 143 | //MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true); |
| 144 | #endif | 144 | #endif |
| 145 | } | 145 | } |
| 146 | #ifdef _WIN32 | 146 | #ifdef _WIN32 |
| 147 | COORD ConsoleListener::GetCoordinates(int BytesRead, int BufferWidth) | 147 | COORD ConsoleListener::GetCoordinates(int BytesRead, int BufferWidth) |
| 148 | { | 148 | { |
| 149 | COORD Ret = {0, 0}; | 149 | COORD Ret = {0, 0}; |
| 150 | // Full rows | 150 | // Full rows |
| 151 | int Step = (int)floor((float)BytesRead / (float)BufferWidth); | 151 | int Step = (int)floor((float)BytesRead / (float)BufferWidth); |
| 152 | Ret.Y += Step; | 152 | Ret.Y += Step; |
| 153 | // Partial row | 153 | // Partial row |
| 154 | Ret.X = BytesRead - (BufferWidth * Step); | 154 | Ret.X = BytesRead - (BufferWidth * Step); |
| 155 | return Ret; | 155 | return Ret; |
| 156 | } | 156 | } |
| 157 | #endif | 157 | #endif |
| 158 | void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize) | 158 | void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize) |
| 159 | { | 159 | { |
| 160 | #ifdef _WIN32 | 160 | #ifdef _WIN32 |
| 161 | // Check size | 161 | // Check size |
| 162 | if (Width < 8 || Height < 12) return; | 162 | if (Width < 8 || Height < 12) return; |
| 163 | 163 | ||
| 164 | bool DBef = true; | 164 | bool DBef = true; |
| 165 | bool DAft = true; | 165 | bool DAft = true; |
| 166 | std::string SLog = ""; | 166 | std::string SLog = ""; |
| 167 | 167 | ||
| 168 | const HWND hWnd = GetConsoleWindow(); | 168 | const HWND hWnd = GetConsoleWindow(); |
| 169 | const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | 169 | const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); |
| 170 | 170 | ||
| 171 | // Get console info | 171 | // Get console info |
| 172 | CONSOLE_SCREEN_BUFFER_INFO ConInfo; | 172 | CONSOLE_SCREEN_BUFFER_INFO ConInfo; |
| 173 | GetConsoleScreenBufferInfo(hConsole, &ConInfo); | 173 | GetConsoleScreenBufferInfo(hConsole, &ConInfo); |
| 174 | DWORD BufferSize = ConInfo.dwSize.X * ConInfo.dwSize.Y; | 174 | DWORD BufferSize = ConInfo.dwSize.X * ConInfo.dwSize.Y; |
| 175 | 175 | ||
| 176 | // --------------------------------------------------------------------- | 176 | // --------------------------------------------------------------------- |
| 177 | // Save the current text | 177 | // Save the current text |
| 178 | // ------------------------ | 178 | // ------------------------ |
| 179 | DWORD cCharsRead = 0; | 179 | DWORD cCharsRead = 0; |
| 180 | COORD coordScreen = { 0, 0 }; | 180 | COORD coordScreen = { 0, 0 }; |
| 181 | 181 | ||
| 182 | static const int MAX_BYTES = 1024 * 16; | 182 | static const int MAX_BYTES = 1024 * 16; |
| 183 | 183 | ||
| 184 | std::vector<std::array<TCHAR, MAX_BYTES>> Str; | 184 | std::vector<std::array<TCHAR, MAX_BYTES>> Str; |
| 185 | std::vector<std::array<WORD, MAX_BYTES>> Attr; | 185 | std::vector<std::array<WORD, MAX_BYTES>> Attr; |
| 186 | 186 | ||
| 187 | // ReadConsoleOutputAttribute seems to have a limit at this level | 187 | // ReadConsoleOutputAttribute seems to have a limit at this level |
| 188 | static const int ReadBufferSize = MAX_BYTES - 32; | 188 | static const int ReadBufferSize = MAX_BYTES - 32; |
| 189 | 189 | ||
| 190 | DWORD cAttrRead = ReadBufferSize; | 190 | DWORD cAttrRead = ReadBufferSize; |
| 191 | DWORD BytesRead = 0; | 191 | DWORD BytesRead = 0; |
| 192 | while (BytesRead < BufferSize) | 192 | while (BytesRead < BufferSize) |
| 193 | { | 193 | { |
| 194 | Str.resize(Str.size() + 1); | 194 | Str.resize(Str.size() + 1); |
| 195 | if (!ReadConsoleOutputCharacter(hConsole, Str.back().data(), ReadBufferSize, coordScreen, &cCharsRead)) | 195 | if (!ReadConsoleOutputCharacter(hConsole, Str.back().data(), ReadBufferSize, coordScreen, &cCharsRead)) |
| 196 | SLog += StringFromFormat("WriteConsoleOutputCharacter error"); | 196 | SLog += StringFromFormat("WriteConsoleOutputCharacter error"); |
| 197 | 197 | ||
| 198 | Attr.resize(Attr.size() + 1); | 198 | Attr.resize(Attr.size() + 1); |
| 199 | if (!ReadConsoleOutputAttribute(hConsole, Attr.back().data(), ReadBufferSize, coordScreen, &cAttrRead)) | 199 | if (!ReadConsoleOutputAttribute(hConsole, Attr.back().data(), ReadBufferSize, coordScreen, &cAttrRead)) |
| 200 | SLog += StringFromFormat("WriteConsoleOutputAttribute error"); | 200 | SLog += StringFromFormat("WriteConsoleOutputAttribute error"); |
| 201 | 201 | ||
| 202 | // Break on error | 202 | // Break on error |
| 203 | if (cAttrRead == 0) break; | 203 | if (cAttrRead == 0) break; |
| 204 | BytesRead += cAttrRead; | 204 | BytesRead += cAttrRead; |
| 205 | coordScreen = GetCoordinates(BytesRead, ConInfo.dwSize.X); | 205 | coordScreen = GetCoordinates(BytesRead, ConInfo.dwSize.X); |
| 206 | } | 206 | } |
| 207 | // Letter space | 207 | // Letter space |
| 208 | int LWidth = (int)(floor((float)Width / 8.0f) - 1.0f); | 208 | int LWidth = (int)(floor((float)Width / 8.0f) - 1.0f); |
| 209 | int LHeight = (int)(floor((float)Height / 12.0f) - 1.0f); | 209 | int LHeight = (int)(floor((float)Height / 12.0f) - 1.0f); |
| 210 | int LBufWidth = LWidth + 1; | 210 | int LBufWidth = LWidth + 1; |
| 211 | int LBufHeight = (int)floor((float)BufferSize / (float)LBufWidth); | 211 | int LBufHeight = (int)floor((float)BufferSize / (float)LBufWidth); |
| 212 | // Change screen buffer size | 212 | // Change screen buffer size |
| 213 | LetterSpace(LBufWidth, LBufHeight); | 213 | LetterSpace(LBufWidth, LBufHeight); |
| 214 | 214 | ||
| 215 | 215 | ||
| 216 | ClearScreen(true); | 216 | ClearScreen(true); |
| 217 | coordScreen.Y = 0; | 217 | coordScreen.Y = 0; |
| 218 | coordScreen.X = 0; | 218 | coordScreen.X = 0; |
| 219 | DWORD cCharsWritten = 0; | 219 | DWORD cCharsWritten = 0; |
| 220 | 220 | ||
| 221 | int BytesWritten = 0; | 221 | int BytesWritten = 0; |
| 222 | DWORD cAttrWritten = 0; | 222 | DWORD cAttrWritten = 0; |
| 223 | for (size_t i = 0; i < Attr.size(); i++) | 223 | for (size_t i = 0; i < Attr.size(); i++) |
| 224 | { | 224 | { |
| 225 | if (!WriteConsoleOutputCharacter(hConsole, Str[i].data(), ReadBufferSize, coordScreen, &cCharsWritten)) | 225 | if (!WriteConsoleOutputCharacter(hConsole, Str[i].data(), ReadBufferSize, coordScreen, &cCharsWritten)) |
| 226 | SLog += StringFromFormat("WriteConsoleOutputCharacter error"); | 226 | SLog += StringFromFormat("WriteConsoleOutputCharacter error"); |
| 227 | if (!WriteConsoleOutputAttribute(hConsole, Attr[i].data(), ReadBufferSize, coordScreen, &cAttrWritten)) | 227 | if (!WriteConsoleOutputAttribute(hConsole, Attr[i].data(), ReadBufferSize, coordScreen, &cAttrWritten)) |
| 228 | SLog += StringFromFormat("WriteConsoleOutputAttribute error"); | 228 | SLog += StringFromFormat("WriteConsoleOutputAttribute error"); |
| 229 | 229 | ||
| 230 | BytesWritten += cAttrWritten; | 230 | BytesWritten += cAttrWritten; |
| 231 | coordScreen = GetCoordinates(BytesWritten, LBufWidth); | 231 | coordScreen = GetCoordinates(BytesWritten, LBufWidth); |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | const int OldCursor = ConInfo.dwCursorPosition.Y * ConInfo.dwSize.X + ConInfo.dwCursorPosition.X; | 234 | const int OldCursor = ConInfo.dwCursorPosition.Y * ConInfo.dwSize.X + ConInfo.dwCursorPosition.X; |
| 235 | COORD Coo = GetCoordinates(OldCursor, LBufWidth); | 235 | COORD Coo = GetCoordinates(OldCursor, LBufWidth); |
| 236 | SetConsoleCursorPosition(hConsole, Coo); | 236 | SetConsoleCursorPosition(hConsole, Coo); |
| 237 | 237 | ||
| 238 | if (SLog.length() > 0) Log(LogTypes::LNOTICE, SLog.c_str()); | 238 | if (SLog.length() > 0) Log(LogTypes::LNOTICE, SLog.c_str()); |
| 239 | 239 | ||
| 240 | // Resize the window too | 240 | // Resize the window too |
| 241 | if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 100),Height, true); | 241 | if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 100),Height, true); |
| 242 | #endif | 242 | #endif |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text) | 245 | void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text) |
| 246 | { | 246 | { |
| 247 | #if defined(_WIN32) | 247 | #if defined(_WIN32) |
| 248 | /* | 248 | /* |
| 249 | const int MAX_BYTES = 1024*10; | 249 | const int MAX_BYTES = 1024*10; |
| 250 | char Str[MAX_BYTES]; | 250 | char Str[MAX_BYTES]; |
| 251 | va_list ArgPtr; | 251 | va_list ArgPtr; |
| 252 | int Cnt; | 252 | int Cnt; |
| 253 | va_start(ArgPtr, Text); | 253 | va_start(ArgPtr, Text); |
| 254 | Cnt = vsnprintf(Str, MAX_BYTES, Text, ArgPtr); | 254 | Cnt = vsnprintf(Str, MAX_BYTES, Text, ArgPtr); |
| 255 | va_end(ArgPtr); | 255 | va_end(ArgPtr); |
| 256 | */ | 256 | */ |
| 257 | DWORD cCharsWritten; | 257 | DWORD cCharsWritten; |
| 258 | WORD Color; | 258 | WORD Color; |
| 259 | 259 | ||
| 260 | switch (Level) | 260 | switch (Level) |
| 261 | { | 261 | { |
| 262 | case NOTICE_LEVEL: // light green | 262 | case NOTICE_LEVEL: // light green |
| 263 | Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY; | 263 | Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY; |
| 264 | break; | 264 | break; |
| 265 | case ERROR_LEVEL: // light red | 265 | case ERROR_LEVEL: // light red |
| 266 | Color = FOREGROUND_RED | FOREGROUND_INTENSITY; | 266 | Color = FOREGROUND_RED | FOREGROUND_INTENSITY; |
| 267 | break; | 267 | break; |
| 268 | case WARNING_LEVEL: // light yellow | 268 | case WARNING_LEVEL: // light yellow |
| 269 | Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; | 269 | Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; |
| 270 | break; | 270 | break; |
| 271 | case INFO_LEVEL: // cyan | 271 | case INFO_LEVEL: // cyan |
| 272 | Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; | 272 | Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; |
| 273 | break; | 273 | break; |
| 274 | case DEBUG_LEVEL: // gray | 274 | case DEBUG_LEVEL: // gray |
| 275 | Color = FOREGROUND_INTENSITY; | 275 | Color = FOREGROUND_INTENSITY; |
| 276 | break; | 276 | break; |
| 277 | default: // off-white | 277 | default: // off-white |
| 278 | Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; | 278 | Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; |
| 279 | break; | 279 | break; |
| 280 | } | 280 | } |
| 281 | if (strlen(Text) > 10) | 281 | if (strlen(Text) > 10) |
| 282 | { | 282 | { |
| 283 | // First 10 chars white | 283 | // First 10 chars white |
| 284 | SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); | 284 | SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); |
| 285 | WriteConsole(hConsole, Text, 10, &cCharsWritten, NULL); | 285 | WriteConsole(hConsole, Text, 10, &cCharsWritten, NULL); |
| 286 | Text += 10; | 286 | Text += 10; |
| 287 | } | 287 | } |
| 288 | SetConsoleTextAttribute(hConsole, Color); | 288 | SetConsoleTextAttribute(hConsole, Color); |
| 289 | WriteConsole(hConsole, Text, (DWORD)strlen(Text), &cCharsWritten, NULL); | 289 | WriteConsole(hConsole, Text, (DWORD)strlen(Text), &cCharsWritten, NULL); |
| 290 | #else | 290 | #else |
| 291 | char ColorAttr[16] = ""; | 291 | char ColorAttr[16] = ""; |
| 292 | char ResetAttr[16] = ""; | 292 | char ResetAttr[16] = ""; |
| 293 | 293 | ||
| 294 | if (bUseColor) | 294 | if (bUseColor) |
| 295 | { | 295 | { |
| 296 | strcpy(ResetAttr, "\033[0m"); | 296 | strcpy(ResetAttr, "\033[0m"); |
| 297 | switch (Level) | 297 | switch (Level) |
| 298 | { | 298 | { |
| 299 | case NOTICE_LEVEL: // light green | 299 | case NOTICE_LEVEL: // light green |
| 300 | strcpy(ColorAttr, "\033[92m"); | 300 | strcpy(ColorAttr, "\033[92m"); |
| 301 | break; | 301 | break; |
| 302 | case ERROR_LEVEL: // light red | 302 | case ERROR_LEVEL: // light red |
| 303 | strcpy(ColorAttr, "\033[91m"); | 303 | strcpy(ColorAttr, "\033[91m"); |
| 304 | break; | 304 | break; |
| 305 | case WARNING_LEVEL: // light yellow | 305 | case WARNING_LEVEL: // light yellow |
| 306 | strcpy(ColorAttr, "\033[93m"); | 306 | strcpy(ColorAttr, "\033[93m"); |
| 307 | break; | 307 | break; |
| 308 | default: | 308 | default: |
| 309 | break; | 309 | break; |
| 310 | } | 310 | } |
| 311 | } | 311 | } |
| 312 | fprintf(stderr, "%s%s%s", ColorAttr, Text, ResetAttr); | 312 | fprintf(stderr, "%s%s%s", ColorAttr, Text, ResetAttr); |
| 313 | #endif | 313 | #endif |
| 314 | } | 314 | } |
| 315 | // Clear console screen | 315 | // Clear console screen |
| 316 | void ConsoleListener::ClearScreen(bool Cursor) | 316 | void ConsoleListener::ClearScreen(bool Cursor) |
| 317 | { | 317 | { |
| 318 | #if defined(_WIN32) | 318 | #if defined(_WIN32) |
| 319 | COORD coordScreen = { 0, 0 }; | 319 | COORD coordScreen = { 0, 0 }; |
| 320 | DWORD cCharsWritten; | 320 | DWORD cCharsWritten; |
| 321 | CONSOLE_SCREEN_BUFFER_INFO csbi; | 321 | CONSOLE_SCREEN_BUFFER_INFO csbi; |
| 322 | DWORD dwConSize; | 322 | DWORD dwConSize; |
| 323 | 323 | ||
| 324 | HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | 324 | HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); |
| 325 | 325 | ||
| 326 | GetConsoleScreenBufferInfo(hConsole, &csbi); | 326 | GetConsoleScreenBufferInfo(hConsole, &csbi); |
| 327 | dwConSize = csbi.dwSize.X * csbi.dwSize.Y; | 327 | dwConSize = csbi.dwSize.X * csbi.dwSize.Y; |
| 328 | // Write space to the entire console | 328 | // Write space to the entire console |
| 329 | FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten); | 329 | FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten); |
| 330 | GetConsoleScreenBufferInfo(hConsole, &csbi); | 330 | GetConsoleScreenBufferInfo(hConsole, &csbi); |
| 331 | FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten); | 331 | FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten); |
| 332 | // Reset cursor | 332 | // Reset cursor |
| 333 | if (Cursor) SetConsoleCursorPosition(hConsole, coordScreen); | 333 | if (Cursor) SetConsoleCursorPosition(hConsole, coordScreen); |
| 334 | #endif | 334 | #endif |
| 335 | } | 335 | } |
| 336 | 336 | ||
diff --git a/src/common/src/console_listener.h b/src/common/src/console_listener.h index ab5c00980..a2936050d 100644 --- a/src/common/src/console_listener.h +++ b/src/common/src/console_listener.h | |||
| @@ -14,28 +14,28 @@ | |||
| 14 | class ConsoleListener : public LogListener | 14 | class ConsoleListener : public LogListener |
| 15 | { | 15 | { |
| 16 | public: | 16 | public: |
| 17 | ConsoleListener(); | 17 | ConsoleListener(); |
| 18 | ~ConsoleListener(); | 18 | ~ConsoleListener(); |
| 19 | 19 | ||
| 20 | void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console"); | 20 | void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console"); |
| 21 | void UpdateHandle(); | 21 | void UpdateHandle(); |
| 22 | void Close(); | 22 | void Close(); |
| 23 | bool IsOpen(); | 23 | bool IsOpen(); |
| 24 | void LetterSpace(int Width, int Height); | 24 | void LetterSpace(int Width, int Height); |
| 25 | void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst); | 25 | void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst); |
| 26 | void PixelSpace(int Left, int Top, int Width, int Height, bool); | 26 | void PixelSpace(int Left, int Top, int Width, int Height, bool); |
| 27 | #ifdef _WIN32 | 27 | #ifdef _WIN32 |
| 28 | COORD GetCoordinates(int BytesRead, int BufferWidth); | 28 | COORD GetCoordinates(int BytesRead, int BufferWidth); |
| 29 | #endif | 29 | #endif |
| 30 | void Log(LogTypes::LOG_LEVELS, const char *Text); | 30 | void Log(LogTypes::LOG_LEVELS, const char *Text); |
| 31 | void ClearScreen(bool Cursor = true); | 31 | void ClearScreen(bool Cursor = true); |
| 32 | 32 | ||
| 33 | private: | 33 | private: |
| 34 | #ifdef _WIN32 | 34 | #ifdef _WIN32 |
| 35 | HWND GetHwnd(void); | 35 | HWND GetHwnd(void); |
| 36 | HANDLE hConsole; | 36 | HANDLE hConsole; |
| 37 | #endif | 37 | #endif |
| 38 | bool bUseColor; | 38 | bool bUseColor; |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | #endif // _CONSOLELISTENER_H | 41 | #endif // _CONSOLELISTENER_H |
diff --git a/src/common/src/cpu_detect.h b/src/common/src/cpu_detect.h index be6ce3498..e93cf333a 100644 --- a/src/common/src/cpu_detect.h +++ b/src/common/src/cpu_detect.h | |||
| @@ -11,69 +11,69 @@ | |||
| 11 | 11 | ||
| 12 | enum CPUVendor | 12 | enum CPUVendor |
| 13 | { | 13 | { |
| 14 | VENDOR_INTEL = 0, | 14 | VENDOR_INTEL = 0, |
| 15 | VENDOR_AMD = 1, | 15 | VENDOR_AMD = 1, |
| 16 | VENDOR_ARM = 2, | 16 | VENDOR_ARM = 2, |
| 17 | VENDOR_OTHER = 3, | 17 | VENDOR_OTHER = 3, |
| 18 | }; | 18 | }; |
| 19 | 19 | ||
| 20 | struct CPUInfo | 20 | struct CPUInfo |
| 21 | { | 21 | { |
| 22 | CPUVendor vendor; | 22 | CPUVendor vendor; |
| 23 | 23 | ||
| 24 | char cpu_string[0x21]; | 24 | char cpu_string[0x21]; |
| 25 | char brand_string[0x41]; | 25 | char brand_string[0x41]; |
| 26 | bool OS64bit; | 26 | bool OS64bit; |
| 27 | bool CPU64bit; | 27 | bool CPU64bit; |
| 28 | bool Mode64bit; | 28 | bool Mode64bit; |
| 29 | 29 | ||
| 30 | bool HTT; | 30 | bool HTT; |
| 31 | int num_cores; | 31 | int num_cores; |
| 32 | int logical_cpu_count; | 32 | int logical_cpu_count; |
| 33 | 33 | ||
| 34 | bool bSSE; | 34 | bool bSSE; |
| 35 | bool bSSE2; | 35 | bool bSSE2; |
| 36 | bool bSSE3; | 36 | bool bSSE3; |
| 37 | bool bSSSE3; | 37 | bool bSSSE3; |
| 38 | bool bPOPCNT; | 38 | bool bPOPCNT; |
| 39 | bool bSSE4_1; | 39 | bool bSSE4_1; |
| 40 | bool bSSE4_2; | 40 | bool bSSE4_2; |
| 41 | bool bLZCNT; | 41 | bool bLZCNT; |
| 42 | bool bSSE4A; | 42 | bool bSSE4A; |
| 43 | bool bAVX; | 43 | bool bAVX; |
| 44 | bool bAES; | 44 | bool bAES; |
| 45 | bool bLAHFSAHF64; | 45 | bool bLAHFSAHF64; |
| 46 | bool bLongMode; | 46 | bool bLongMode; |
| 47 | 47 | ||
| 48 | // ARM specific CPUInfo | 48 | // ARM specific CPUInfo |
| 49 | bool bSwp; | 49 | bool bSwp; |
| 50 | bool bHalf; | 50 | bool bHalf; |
| 51 | bool bThumb; | 51 | bool bThumb; |
| 52 | bool bFastMult; | 52 | bool bFastMult; |
| 53 | bool bVFP; | 53 | bool bVFP; |
| 54 | bool bEDSP; | 54 | bool bEDSP; |
| 55 | bool bThumbEE; | 55 | bool bThumbEE; |
| 56 | bool bNEON; | 56 | bool bNEON; |
| 57 | bool bVFPv3; | 57 | bool bVFPv3; |
| 58 | bool bTLS; | 58 | bool bTLS; |
| 59 | bool bVFPv4; | 59 | bool bVFPv4; |
| 60 | bool bIDIVa; | 60 | bool bIDIVa; |
| 61 | bool bIDIVt; | 61 | bool bIDIVt; |
| 62 | bool bArmV7; // enable MOVT, MOVW etc | 62 | bool bArmV7; // enable MOVT, MOVW etc |
| 63 | 63 | ||
| 64 | // ARMv8 specific | 64 | // ARMv8 specific |
| 65 | bool bFP; | 65 | bool bFP; |
| 66 | bool bASIMD; | 66 | bool bASIMD; |
| 67 | 67 | ||
| 68 | // Call Detect() | 68 | // Call Detect() |
| 69 | explicit CPUInfo(); | 69 | explicit CPUInfo(); |
| 70 | 70 | ||
| 71 | // Turn the cpu info into a string we can show | 71 | // Turn the cpu info into a string we can show |
| 72 | std::string Summarize(); | 72 | std::string Summarize(); |
| 73 | 73 | ||
| 74 | private: | 74 | private: |
| 75 | // Detects the various cpu features | 75 | // Detects the various cpu features |
| 76 | void Detect(); | 76 | void Detect(); |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | extern CPUInfo cpu_info; | 79 | extern CPUInfo cpu_info; |
diff --git a/src/common/src/debug_interface.h b/src/common/src/debug_interface.h index 317cd0bb4..49cc54a80 100644 --- a/src/common/src/debug_interface.h +++ b/src/common/src/debug_interface.h | |||
| @@ -7,33 +7,33 @@ | |||
| 7 | class DebugInterface | 7 | class DebugInterface |
| 8 | { | 8 | { |
| 9 | protected: | 9 | protected: |
| 10 | virtual ~DebugInterface() {} | 10 | virtual ~DebugInterface() {} |
| 11 | 11 | ||
| 12 | public: | 12 | public: |
| 13 | virtual void disasm(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} | 13 | virtual void disasm(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} |
| 14 | virtual void getRawMemoryString(int /*memory*/, unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} | 14 | virtual void getRawMemoryString(int /*memory*/, unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} |
| 15 | virtual int getInstructionSize(int /*instruction*/) {return 1;} | 15 | virtual int getInstructionSize(int /*instruction*/) {return 1;} |
| 16 | virtual bool isAlive() {return true;} | 16 | virtual bool isAlive() {return true;} |
| 17 | virtual bool isBreakpoint(unsigned int /*address*/) {return false;} | 17 | virtual bool isBreakpoint(unsigned int /*address*/) {return false;} |
| 18 | virtual void setBreakpoint(unsigned int /*address*/){} | 18 | virtual void setBreakpoint(unsigned int /*address*/){} |
| 19 | virtual void clearBreakpoint(unsigned int /*address*/){} | 19 | virtual void clearBreakpoint(unsigned int /*address*/){} |
| 20 | virtual void clearAllBreakpoints() {} | 20 | virtual void clearAllBreakpoints() {} |
| 21 | virtual void toggleBreakpoint(unsigned int /*address*/){} | 21 | virtual void toggleBreakpoint(unsigned int /*address*/){} |
| 22 | virtual bool isMemCheck(unsigned int /*address*/) {return false;} | 22 | virtual bool isMemCheck(unsigned int /*address*/) {return false;} |
| 23 | virtual void toggleMemCheck(unsigned int /*address*/){} | 23 | virtual void toggleMemCheck(unsigned int /*address*/){} |
| 24 | virtual unsigned int readMemory(unsigned int /*address*/){return 0;} | 24 | virtual unsigned int readMemory(unsigned int /*address*/){return 0;} |
| 25 | virtual void writeExtraMemory(int /*memory*/, unsigned int /*value*/, unsigned int /*address*/) {} | 25 | virtual void writeExtraMemory(int /*memory*/, unsigned int /*value*/, unsigned int /*address*/) {} |
| 26 | virtual unsigned int readExtraMemory(int /*memory*/, unsigned int /*address*/){return 0;} | 26 | virtual unsigned int readExtraMemory(int /*memory*/, unsigned int /*address*/){return 0;} |
| 27 | virtual unsigned int readInstruction(unsigned int /*address*/){return 0;} | 27 | virtual unsigned int readInstruction(unsigned int /*address*/){return 0;} |
| 28 | virtual unsigned int getPC() {return 0;} | 28 | virtual unsigned int getPC() {return 0;} |
| 29 | virtual void setPC(unsigned int /*address*/) {} | 29 | virtual void setPC(unsigned int /*address*/) {} |
| 30 | virtual void step() {} | 30 | virtual void step() {} |
| 31 | virtual void runToBreakpoint() {} | 31 | virtual void runToBreakpoint() {} |
| 32 | virtual void breakNow() {} | 32 | virtual void breakNow() {} |
| 33 | virtual void insertBLR(unsigned int /*address*/, unsigned int /*value*/) {} | 33 | virtual void insertBLR(unsigned int /*address*/, unsigned int /*value*/) {} |
| 34 | virtual void showJitResults(unsigned int /*address*/) {}; | 34 | virtual void showJitResults(unsigned int /*address*/) {}; |
| 35 | virtual int getColor(unsigned int /*address*/){return 0xFFFFFFFF;} | 35 | virtual int getColor(unsigned int /*address*/){return 0xFFFFFFFF;} |
| 36 | virtual std::string getDescription(unsigned int /*address*/) = 0; | 36 | virtual std::string getDescription(unsigned int /*address*/) = 0; |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | #endif | 39 | #endif |
diff --git a/src/common/src/emu_window.h b/src/common/src/emu_window.h index 2427b5b6a..66de75574 100644 --- a/src/common/src/emu_window.h +++ b/src/common/src/emu_window.h | |||
| @@ -48,8 +48,8 @@ public: | |||
| 48 | /// Swap buffers to display the next frame | 48 | /// Swap buffers to display the next frame |
| 49 | virtual void SwapBuffers() = 0; | 49 | virtual void SwapBuffers() = 0; |
| 50 | 50 | ||
| 51 | /// Polls window events | 51 | /// Polls window events |
| 52 | virtual void PollEvents() = 0; | 52 | virtual void PollEvents() = 0; |
| 53 | 53 | ||
| 54 | /// Makes the graphics context current for the caller thread | 54 | /// Makes the graphics context current for the caller thread |
| 55 | virtual void MakeCurrent() = 0; | 55 | virtual void MakeCurrent() = 0; |
diff --git a/src/common/src/extended_trace.cpp b/src/common/src/extended_trace.cpp index 44815343d..9f717dba3 100644 --- a/src/common/src/extended_trace.cpp +++ b/src/common/src/extended_trace.cpp | |||
| @@ -30,18 +30,18 @@ using namespace std; | |||
| 30 | void PCSTR2LPTSTR( PCSTR lpszIn, LPTSTR lpszOut ) | 30 | void PCSTR2LPTSTR( PCSTR lpszIn, LPTSTR lpszOut ) |
| 31 | { | 31 | { |
| 32 | #if defined(UNICODE)||defined(_UNICODE) | 32 | #if defined(UNICODE)||defined(_UNICODE) |
| 33 | ULONG index = 0; | 33 | ULONG index = 0; |
| 34 | PCSTR lpAct = lpszIn; | 34 | PCSTR lpAct = lpszIn; |
| 35 | 35 | ||
| 36 | for( ; ; lpAct++ ) | 36 | for( ; ; lpAct++ ) |
| 37 | { | 37 | { |
| 38 | lpszOut[index++] = (TCHAR)(*lpAct); | 38 | lpszOut[index++] = (TCHAR)(*lpAct); |
| 39 | if ( *lpAct == 0 ) | 39 | if ( *lpAct == 0 ) |
| 40 | break; | 40 | break; |
| 41 | } | 41 | } |
| 42 | #else | 42 | #else |
| 43 | // This is trivial :) | 43 | // This is trivial :) |
| 44 | strcpy( lpszOut, lpszIn ); | 44 | strcpy( lpszOut, lpszIn ); |
| 45 | #endif | 45 | #endif |
| 46 | } | 46 | } |
| 47 | 47 | ||
| @@ -50,184 +50,184 @@ void PCSTR2LPTSTR( PCSTR lpszIn, LPTSTR lpszOut ) | |||
| 50 | // Note: There is no size check for lpszSymbolPath! | 50 | // Note: There is no size check for lpszSymbolPath! |
| 51 | static void InitSymbolPath( PSTR lpszSymbolPath, PCSTR lpszIniPath ) | 51 | static void InitSymbolPath( PSTR lpszSymbolPath, PCSTR lpszIniPath ) |
| 52 | { | 52 | { |
| 53 | CHAR lpszPath[BUFFERSIZE]; | 53 | CHAR lpszPath[BUFFERSIZE]; |
| 54 | 54 | ||
| 55 | // Creating the default path | 55 | // Creating the default path |
| 56 | // ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%SYSTEMROOT%;%SYSTEMROOT%\System32;" | 56 | // ".;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%;%SYSTEMROOT%;%SYSTEMROOT%\System32;" |
| 57 | strcpy( lpszSymbolPath, "." ); | 57 | strcpy( lpszSymbolPath, "." ); |
| 58 | 58 | ||
| 59 | // environment variable _NT_SYMBOL_PATH | 59 | // environment variable _NT_SYMBOL_PATH |
| 60 | if ( GetEnvironmentVariableA( "_NT_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) | 60 | if ( GetEnvironmentVariableA( "_NT_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) |
| 61 | { | 61 | { |
| 62 | strcat( lpszSymbolPath, ";" ); | 62 | strcat( lpszSymbolPath, ";" ); |
| 63 | strcat( lpszSymbolPath, lpszPath ); | 63 | strcat( lpszSymbolPath, lpszPath ); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | // environment variable _NT_ALTERNATE_SYMBOL_PATH | 66 | // environment variable _NT_ALTERNATE_SYMBOL_PATH |
| 67 | if ( GetEnvironmentVariableA( "_NT_ALTERNATE_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) | 67 | if ( GetEnvironmentVariableA( "_NT_ALTERNATE_SYMBOL_PATH", lpszPath, BUFFERSIZE ) ) |
| 68 | { | 68 | { |
| 69 | strcat( lpszSymbolPath, ";" ); | 69 | strcat( lpszSymbolPath, ";" ); |
| 70 | strcat( lpszSymbolPath, lpszPath ); | 70 | strcat( lpszSymbolPath, lpszPath ); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | // environment variable SYSTEMROOT | 73 | // environment variable SYSTEMROOT |
| 74 | if ( GetEnvironmentVariableA( "SYSTEMROOT", lpszPath, BUFFERSIZE ) ) | 74 | if ( GetEnvironmentVariableA( "SYSTEMROOT", lpszPath, BUFFERSIZE ) ) |
| 75 | { | 75 | { |
| 76 | strcat( lpszSymbolPath, ";" ); | 76 | strcat( lpszSymbolPath, ";" ); |
| 77 | strcat( lpszSymbolPath, lpszPath ); | 77 | strcat( lpszSymbolPath, lpszPath ); |
| 78 | strcat( lpszSymbolPath, ";" ); | 78 | strcat( lpszSymbolPath, ";" ); |
| 79 | 79 | ||
| 80 | // SYSTEMROOT\System32 | 80 | // SYSTEMROOT\System32 |
| 81 | strcat( lpszSymbolPath, lpszPath ); | 81 | strcat( lpszSymbolPath, lpszPath ); |
| 82 | strcat( lpszSymbolPath, "\\System32" ); | 82 | strcat( lpszSymbolPath, "\\System32" ); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | // Add user defined path | 85 | // Add user defined path |
| 86 | if ( lpszIniPath != NULL ) | 86 | if ( lpszIniPath != NULL ) |
| 87 | if ( lpszIniPath[0] != '\0' ) | 87 | if ( lpszIniPath[0] != '\0' ) |
| 88 | { | 88 | { |
| 89 | strcat( lpszSymbolPath, ";" ); | 89 | strcat( lpszSymbolPath, ";" ); |
| 90 | strcat( lpszSymbolPath, lpszIniPath ); | 90 | strcat( lpszSymbolPath, lpszIniPath ); |
| 91 | } | 91 | } |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | // Uninitialize the loaded symbol files | 94 | // Uninitialize the loaded symbol files |
| 95 | BOOL UninitSymInfo() { | 95 | BOOL UninitSymInfo() { |
| 96 | return SymCleanup( GetCurrentProcess() ); | 96 | return SymCleanup( GetCurrentProcess() ); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | // Initializes the symbol files | 99 | // Initializes the symbol files |
| 100 | BOOL InitSymInfo( PCSTR lpszInitialSymbolPath ) | 100 | BOOL InitSymInfo( PCSTR lpszInitialSymbolPath ) |
| 101 | { | 101 | { |
| 102 | CHAR lpszSymbolPath[BUFFERSIZE]; | 102 | CHAR lpszSymbolPath[BUFFERSIZE]; |
| 103 | DWORD symOptions = SymGetOptions(); | 103 | DWORD symOptions = SymGetOptions(); |
| 104 | 104 | ||
| 105 | symOptions |= SYMOPT_LOAD_LINES; | 105 | symOptions |= SYMOPT_LOAD_LINES; |
| 106 | symOptions &= ~SYMOPT_UNDNAME; | 106 | symOptions &= ~SYMOPT_UNDNAME; |
| 107 | SymSetOptions( symOptions ); | 107 | SymSetOptions( symOptions ); |
| 108 | InitSymbolPath( lpszSymbolPath, lpszInitialSymbolPath ); | 108 | InitSymbolPath( lpszSymbolPath, lpszInitialSymbolPath ); |
| 109 | 109 | ||
| 110 | return SymInitialize( GetCurrentProcess(), lpszSymbolPath, TRUE); | 110 | return SymInitialize( GetCurrentProcess(), lpszSymbolPath, TRUE); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | // Get the module name from a given address | 113 | // Get the module name from a given address |
| 114 | static BOOL GetModuleNameFromAddress( UINT address, LPTSTR lpszModule ) | 114 | static BOOL GetModuleNameFromAddress( UINT address, LPTSTR lpszModule ) |
| 115 | { | 115 | { |
| 116 | BOOL ret = FALSE; | 116 | BOOL ret = FALSE; |
| 117 | IMAGEHLP_MODULE moduleInfo; | 117 | IMAGEHLP_MODULE moduleInfo; |
| 118 | 118 | ||
| 119 | ::ZeroMemory( &moduleInfo, sizeof(moduleInfo) ); | 119 | ::ZeroMemory( &moduleInfo, sizeof(moduleInfo) ); |
| 120 | moduleInfo.SizeOfStruct = sizeof(moduleInfo); | 120 | moduleInfo.SizeOfStruct = sizeof(moduleInfo); |
| 121 | 121 | ||
| 122 | if ( SymGetModuleInfo( GetCurrentProcess(), (DWORD)address, &moduleInfo ) ) | 122 | if ( SymGetModuleInfo( GetCurrentProcess(), (DWORD)address, &moduleInfo ) ) |
| 123 | { | 123 | { |
| 124 | // Got it! | 124 | // Got it! |
| 125 | PCSTR2LPTSTR( moduleInfo.ModuleName, lpszModule ); | 125 | PCSTR2LPTSTR( moduleInfo.ModuleName, lpszModule ); |
| 126 | ret = TRUE; | 126 | ret = TRUE; |
| 127 | } | 127 | } |
| 128 | else | 128 | else |
| 129 | // Not found :( | 129 | // Not found :( |
| 130 | _tcscpy( lpszModule, _T("?") ); | 130 | _tcscpy( lpszModule, _T("?") ); |
| 131 | 131 | ||
| 132 | return ret; | 132 | return ret; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | // Get function prototype and parameter info from ip address and stack address | 135 | // Get function prototype and parameter info from ip address and stack address |
| 136 | static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, LPTSTR lpszSymbol ) | 136 | static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, LPTSTR lpszSymbol ) |
| 137 | { | 137 | { |
| 138 | BOOL ret = FALSE; | 138 | BOOL ret = FALSE; |
| 139 | DWORD dwSymSize = 10000; | 139 | DWORD dwSymSize = 10000; |
| 140 | TCHAR lpszUnDSymbol[BUFFERSIZE]=_T("?"); | 140 | TCHAR lpszUnDSymbol[BUFFERSIZE]=_T("?"); |
| 141 | CHAR lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?"; | 141 | CHAR lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?"; |
| 142 | LPTSTR lpszParamSep = NULL; | 142 | LPTSTR lpszParamSep = NULL; |
| 143 | LPTSTR lpszParsed = lpszUnDSymbol; | 143 | LPTSTR lpszParsed = lpszUnDSymbol; |
| 144 | PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize ); | 144 | PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize ); |
| 145 | 145 | ||
| 146 | ::ZeroMemory( pSym, dwSymSize ); | 146 | ::ZeroMemory( pSym, dwSymSize ); |
| 147 | pSym->SizeOfStruct = dwSymSize; | 147 | pSym->SizeOfStruct = dwSymSize; |
| 148 | pSym->MaxNameLength = dwSymSize - sizeof(IMAGEHLP_SYMBOL); | 148 | pSym->MaxNameLength = dwSymSize - sizeof(IMAGEHLP_SYMBOL); |
| 149 | 149 | ||
| 150 | // Set the default to unknown | 150 | // Set the default to unknown |
| 151 | _tcscpy( lpszSymbol, _T("?") ); | 151 | _tcscpy( lpszSymbol, _T("?") ); |
| 152 | 152 | ||
| 153 | // Get symbol info for IP | 153 | // Get symbol info for IP |
| 154 | #ifndef _M_X64 | 154 | #ifndef _M_X64 |
| 155 | DWORD dwDisp = 0; | 155 | DWORD dwDisp = 0; |
| 156 | if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, &dwDisp, pSym ) ) | 156 | if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, &dwDisp, pSym ) ) |
| 157 | #else | 157 | #else |
| 158 | //makes it compile but hell im not sure if this works... | 158 | //makes it compile but hell im not sure if this works... |
| 159 | DWORD64 dwDisp = 0; | 159 | DWORD64 dwDisp = 0; |
| 160 | if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) ) | 160 | if ( SymGetSymFromAddr( GetCurrentProcess(), (ULONG)fnAddress, (PDWORD64)&dwDisp, pSym ) ) |
| 161 | #endif | 161 | #endif |
| 162 | { | 162 | { |
| 163 | // Make the symbol readable for humans | 163 | // Make the symbol readable for humans |
| 164 | UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE, | 164 | UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE, |
| 165 | UNDNAME_COMPLETE | | 165 | UNDNAME_COMPLETE | |
| 166 | UNDNAME_NO_THISTYPE | | 166 | UNDNAME_NO_THISTYPE | |
| 167 | UNDNAME_NO_SPECIAL_SYMS | | 167 | UNDNAME_NO_SPECIAL_SYMS | |
| 168 | UNDNAME_NO_MEMBER_TYPE | | 168 | UNDNAME_NO_MEMBER_TYPE | |
| 169 | UNDNAME_NO_MS_KEYWORDS | | 169 | UNDNAME_NO_MS_KEYWORDS | |
| 170 | UNDNAME_NO_ACCESS_SPECIFIERS ); | 170 | UNDNAME_NO_ACCESS_SPECIFIERS ); |
| 171 | 171 | ||
| 172 | // Symbol information is ANSI string | 172 | // Symbol information is ANSI string |
| 173 | PCSTR2LPTSTR( lpszNonUnicodeUnDSymbol, lpszUnDSymbol ); | 173 | PCSTR2LPTSTR( lpszNonUnicodeUnDSymbol, lpszUnDSymbol ); |
| 174 | 174 | ||
| 175 | // I am just smarter than the symbol file :) | 175 | // I am just smarter than the symbol file :) |
| 176 | if ( _tcscmp(lpszUnDSymbol, _T("_WinMain@16")) == 0 ) | 176 | if ( _tcscmp(lpszUnDSymbol, _T("_WinMain@16")) == 0 ) |
| 177 | _tcscpy(lpszUnDSymbol, _T("WinMain(HINSTANCE,HINSTANCE,LPCTSTR,int)")); | 177 | _tcscpy(lpszUnDSymbol, _T("WinMain(HINSTANCE,HINSTANCE,LPCTSTR,int)")); |
| 178 | else | 178 | else |
| 179 | if ( _tcscmp(lpszUnDSymbol, _T("_main")) == 0 ) | 179 | if ( _tcscmp(lpszUnDSymbol, _T("_main")) == 0 ) |
| 180 | _tcscpy(lpszUnDSymbol, _T("main(int,TCHAR * *)")); | 180 | _tcscpy(lpszUnDSymbol, _T("main(int,TCHAR * *)")); |
| 181 | else | 181 | else |
| 182 | if ( _tcscmp(lpszUnDSymbol, _T("_mainCRTStartup")) == 0 ) | 182 | if ( _tcscmp(lpszUnDSymbol, _T("_mainCRTStartup")) == 0 ) |
| 183 | _tcscpy(lpszUnDSymbol, _T("mainCRTStartup()")); | 183 | _tcscpy(lpszUnDSymbol, _T("mainCRTStartup()")); |
| 184 | else | 184 | else |
| 185 | if ( _tcscmp(lpszUnDSymbol, _T("_wmain")) == 0 ) | 185 | if ( _tcscmp(lpszUnDSymbol, _T("_wmain")) == 0 ) |
| 186 | _tcscpy(lpszUnDSymbol, _T("wmain(int,TCHAR * *,TCHAR * *)")); | 186 | _tcscpy(lpszUnDSymbol, _T("wmain(int,TCHAR * *,TCHAR * *)")); |
| 187 | else | 187 | else |
| 188 | if ( _tcscmp(lpszUnDSymbol, _T("_wmainCRTStartup")) == 0 ) | 188 | if ( _tcscmp(lpszUnDSymbol, _T("_wmainCRTStartup")) == 0 ) |
| 189 | _tcscpy(lpszUnDSymbol, _T("wmainCRTStartup()")); | 189 | _tcscpy(lpszUnDSymbol, _T("wmainCRTStartup()")); |
| 190 | 190 | ||
| 191 | lpszSymbol[0] = _T('\0'); | 191 | lpszSymbol[0] = _T('\0'); |
| 192 | 192 | ||
| 193 | // Let's go through the stack, and modify the function prototype, and insert the actual | 193 | // Let's go through the stack, and modify the function prototype, and insert the actual |
| 194 | // parameter values from the stack | 194 | // parameter values from the stack |
| 195 | if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == NULL && _tcsstr( lpszUnDSymbol, _T("()") ) == NULL) | 195 | if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == NULL && _tcsstr( lpszUnDSymbol, _T("()") ) == NULL) |
| 196 | { | 196 | { |
| 197 | ULONG index = 0; | 197 | ULONG index = 0; |
| 198 | for( ; ; index++ ) | 198 | for( ; ; index++ ) |
| 199 | { | 199 | { |
| 200 | lpszParamSep = _tcschr( lpszParsed, _T(',') ); | 200 | lpszParamSep = _tcschr( lpszParsed, _T(',') ); |
| 201 | if ( lpszParamSep == NULL ) | 201 | if ( lpszParamSep == NULL ) |
| 202 | break; | 202 | break; |
| 203 | 203 | ||
| 204 | *lpszParamSep = _T('\0'); | 204 | *lpszParamSep = _T('\0'); |
| 205 | 205 | ||
| 206 | _tcscat( lpszSymbol, lpszParsed ); | 206 | _tcscat( lpszSymbol, lpszParsed ); |
| 207 | _stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X,"), *((ULONG*)(stackAddress) + 2 + index) ); | 207 | _stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X,"), *((ULONG*)(stackAddress) + 2 + index) ); |
| 208 | 208 | ||
| 209 | lpszParsed = lpszParamSep + 1; | 209 | lpszParsed = lpszParamSep + 1; |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | lpszParamSep = _tcschr( lpszParsed, _T(')') ); | 212 | lpszParamSep = _tcschr( lpszParsed, _T(')') ); |
| 213 | if ( lpszParamSep != NULL ) | 213 | if ( lpszParamSep != NULL ) |
| 214 | { | 214 | { |
| 215 | *lpszParamSep = _T('\0'); | 215 | *lpszParamSep = _T('\0'); |
| 216 | 216 | ||
| 217 | _tcscat( lpszSymbol, lpszParsed ); | 217 | _tcscat( lpszSymbol, lpszParsed ); |
| 218 | _stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X)"), *((ULONG*)(stackAddress) + 2 + index) ); | 218 | _stprintf( lpszSymbol + _tcslen(lpszSymbol), _T("=0x%08X)"), *((ULONG*)(stackAddress) + 2 + index) ); |
| 219 | 219 | ||
| 220 | lpszParsed = lpszParamSep + 1; | 220 | lpszParsed = lpszParamSep + 1; |
| 221 | } | 221 | } |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | _tcscat( lpszSymbol, lpszParsed ); | 224 | _tcscat( lpszSymbol, lpszParsed ); |
| 225 | 225 | ||
| 226 | ret = TRUE; | 226 | ret = TRUE; |
| 227 | } | 227 | } |
| 228 | GlobalFree( pSym ); | 228 | GlobalFree( pSym ); |
| 229 | 229 | ||
| 230 | return ret; | 230 | return ret; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | // Get source file name and line number from IP address | 233 | // Get source file name and line number from IP address |
| @@ -236,198 +236,198 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L | |||
| 236 | // "address" | 236 | // "address" |
| 237 | static BOOL GetSourceInfoFromAddress( UINT address, LPTSTR lpszSourceInfo ) | 237 | static BOOL GetSourceInfoFromAddress( UINT address, LPTSTR lpszSourceInfo ) |
| 238 | { | 238 | { |
| 239 | BOOL ret = FALSE; | 239 | BOOL ret = FALSE; |
| 240 | IMAGEHLP_LINE lineInfo; | 240 | IMAGEHLP_LINE lineInfo; |
| 241 | DWORD dwDisp; | 241 | DWORD dwDisp; |
| 242 | TCHAR lpszFileName[BUFFERSIZE] = _T(""); | 242 | TCHAR lpszFileName[BUFFERSIZE] = _T(""); |
| 243 | TCHAR lpModuleInfo[BUFFERSIZE] = _T(""); | 243 | TCHAR lpModuleInfo[BUFFERSIZE] = _T(""); |
| 244 | 244 | ||
| 245 | _tcscpy( lpszSourceInfo, _T("?(?)") ); | 245 | _tcscpy( lpszSourceInfo, _T("?(?)") ); |
| 246 | 246 | ||
| 247 | ::ZeroMemory( &lineInfo, sizeof( lineInfo ) ); | 247 | ::ZeroMemory( &lineInfo, sizeof( lineInfo ) ); |
| 248 | lineInfo.SizeOfStruct = sizeof( lineInfo ); | 248 | lineInfo.SizeOfStruct = sizeof( lineInfo ); |
| 249 | 249 | ||
| 250 | if ( SymGetLineFromAddr( GetCurrentProcess(), address, &dwDisp, &lineInfo ) ) | 250 | if ( SymGetLineFromAddr( GetCurrentProcess(), address, &dwDisp, &lineInfo ) ) |
| 251 | { | 251 | { |
| 252 | // Got it. Let's use "sourcefile(linenumber)" format | 252 | // Got it. Let's use "sourcefile(linenumber)" format |
| 253 | PCSTR2LPTSTR( lineInfo.FileName, lpszFileName ); | 253 | PCSTR2LPTSTR( lineInfo.FileName, lpszFileName ); |
| 254 | TCHAR fname[_MAX_FNAME]; | 254 | TCHAR fname[_MAX_FNAME]; |
| 255 | TCHAR ext[_MAX_EXT]; | 255 | TCHAR ext[_MAX_EXT]; |
| 256 | _tsplitpath(lpszFileName, NULL, NULL, fname, ext); | 256 | _tsplitpath(lpszFileName, NULL, NULL, fname, ext); |
| 257 | _stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber ); | 257 | _stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber ); |
| 258 | ret = TRUE; | 258 | ret = TRUE; |
| 259 | } | 259 | } |
| 260 | else | 260 | else |
| 261 | { | 261 | { |
| 262 | // There is no source file information. :( | 262 | // There is no source file information. :( |
| 263 | // Let's use the "modulename!address" format | 263 | // Let's use the "modulename!address" format |
| 264 | GetModuleNameFromAddress( address, lpModuleInfo ); | 264 | GetModuleNameFromAddress( address, lpModuleInfo ); |
| 265 | 265 | ||
| 266 | if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0')) | 266 | if ( lpModuleInfo[0] == _T('?') || lpModuleInfo[0] == _T('\0')) |
| 267 | // There is no modulename information. :(( | 267 | // There is no modulename information. :(( |
| 268 | // Let's use the "address" format | 268 | // Let's use the "address" format |
| 269 | _stprintf( lpszSourceInfo, _T("0x%08X"), address ); | 269 | _stprintf( lpszSourceInfo, _T("0x%08X"), address ); |
| 270 | else | 270 | else |
| 271 | _stprintf( lpszSourceInfo, _T("%s!0x%08X"), lpModuleInfo, address ); | 271 | _stprintf( lpszSourceInfo, _T("%s!0x%08X"), lpModuleInfo, address ); |
| 272 | 272 | ||
| 273 | ret = FALSE; | 273 | ret = FALSE; |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | return ret; | 276 | return ret; |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | void PrintFunctionAndSourceInfo(FILE* file, const STACKFRAME& callstack) | 279 | void PrintFunctionAndSourceInfo(FILE* file, const STACKFRAME& callstack) |
| 280 | { | 280 | { |
| 281 | TCHAR symInfo[BUFFERSIZE] = _T("?"); | 281 | TCHAR symInfo[BUFFERSIZE] = _T("?"); |
| 282 | TCHAR srcInfo[BUFFERSIZE] = _T("?"); | 282 | TCHAR srcInfo[BUFFERSIZE] = _T("?"); |
| 283 | 283 | ||
| 284 | GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo); | 284 | GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo); |
| 285 | GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo); | 285 | GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo); |
| 286 | etfprint(file, " " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n"); | 286 | etfprint(file, " " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n"); |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | void StackTrace( HANDLE hThread, const char* lpszMessage, FILE *file ) | 289 | void StackTrace( HANDLE hThread, const char* lpszMessage, FILE *file ) |
| 290 | { | 290 | { |
| 291 | STACKFRAME callStack; | 291 | STACKFRAME callStack; |
| 292 | BOOL bResult; | 292 | BOOL bResult; |
| 293 | CONTEXT context; | 293 | CONTEXT context; |
| 294 | HANDLE hProcess = GetCurrentProcess(); | 294 | HANDLE hProcess = GetCurrentProcess(); |
| 295 | 295 | ||
| 296 | // If it's not this thread, let's suspend it, and resume it at the end | 296 | // If it's not this thread, let's suspend it, and resume it at the end |
| 297 | if ( hThread != GetCurrentThread() ) | 297 | if ( hThread != GetCurrentThread() ) |
| 298 | if ( SuspendThread( hThread ) == -1 ) | 298 | if ( SuspendThread( hThread ) == -1 ) |
| 299 | { | 299 | { |
| 300 | // whaaat ?! | 300 | // whaaat ?! |
| 301 | etfprint(file, "Call stack info failed\n"); | 301 | etfprint(file, "Call stack info failed\n"); |
| 302 | return; | 302 | return; |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | ::ZeroMemory( &context, sizeof(context) ); | 305 | ::ZeroMemory( &context, sizeof(context) ); |
| 306 | context.ContextFlags = CONTEXT_FULL; | 306 | context.ContextFlags = CONTEXT_FULL; |
| 307 | 307 | ||
| 308 | if ( !GetThreadContext( hThread, &context ) ) | 308 | if ( !GetThreadContext( hThread, &context ) ) |
| 309 | { | 309 | { |
| 310 | etfprint(file, "Call stack info failed\n"); | 310 | etfprint(file, "Call stack info failed\n"); |
| 311 | return; | 311 | return; |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | ::ZeroMemory( &callStack, sizeof(callStack) ); | 314 | ::ZeroMemory( &callStack, sizeof(callStack) ); |
| 315 | #ifndef _M_X64 | 315 | #ifndef _M_X64 |
| 316 | callStack.AddrPC.Offset = context.Eip; | 316 | callStack.AddrPC.Offset = context.Eip; |
| 317 | callStack.AddrStack.Offset = context.Esp; | 317 | callStack.AddrStack.Offset = context.Esp; |
| 318 | callStack.AddrFrame.Offset = context.Ebp; | 318 | callStack.AddrFrame.Offset = context.Ebp; |
| 319 | #else | 319 | #else |
| 320 | callStack.AddrPC.Offset = context.Rip; | 320 | callStack.AddrPC.Offset = context.Rip; |
| 321 | callStack.AddrStack.Offset = context.Rsp; | 321 | callStack.AddrStack.Offset = context.Rsp; |
| 322 | callStack.AddrFrame.Offset = context.Rbp; | 322 | callStack.AddrFrame.Offset = context.Rbp; |
| 323 | #endif | 323 | #endif |
| 324 | callStack.AddrPC.Mode = AddrModeFlat; | 324 | callStack.AddrPC.Mode = AddrModeFlat; |
| 325 | callStack.AddrStack.Mode = AddrModeFlat; | 325 | callStack.AddrStack.Mode = AddrModeFlat; |
| 326 | callStack.AddrFrame.Mode = AddrModeFlat; | 326 | callStack.AddrFrame.Mode = AddrModeFlat; |
| 327 | 327 | ||
| 328 | etfprint(file, "Call stack info: \n"); | 328 | etfprint(file, "Call stack info: \n"); |
| 329 | etfprint(file, lpszMessage); | 329 | etfprint(file, lpszMessage); |
| 330 | 330 | ||
| 331 | PrintFunctionAndSourceInfo(file, callStack); | 331 | PrintFunctionAndSourceInfo(file, callStack); |
| 332 | 332 | ||
| 333 | for( ULONG index = 0; ; index++ ) | 333 | for( ULONG index = 0; ; index++ ) |
| 334 | { | 334 | { |
| 335 | bResult = StackWalk( | 335 | bResult = StackWalk( |
| 336 | IMAGE_FILE_MACHINE_I386, | 336 | IMAGE_FILE_MACHINE_I386, |
| 337 | hProcess, | 337 | hProcess, |
| 338 | hThread, | 338 | hThread, |
| 339 | &callStack, | 339 | &callStack, |
| 340 | NULL, | 340 | NULL, |
| 341 | NULL, | 341 | NULL, |
| 342 | SymFunctionTableAccess, | 342 | SymFunctionTableAccess, |
| 343 | SymGetModuleBase, | 343 | SymGetModuleBase, |
| 344 | NULL); | 344 | NULL); |
| 345 | 345 | ||
| 346 | if ( index == 0 ) | 346 | if ( index == 0 ) |
| 347 | continue; | 347 | continue; |
| 348 | 348 | ||
| 349 | if( !bResult || callStack.AddrFrame.Offset == 0 ) | 349 | if( !bResult || callStack.AddrFrame.Offset == 0 ) |
| 350 | break; | 350 | break; |
| 351 | 351 | ||
| 352 | PrintFunctionAndSourceInfo(file, callStack); | 352 | PrintFunctionAndSourceInfo(file, callStack); |
| 353 | 353 | ||
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | if ( hThread != GetCurrentThread() ) | 356 | if ( hThread != GetCurrentThread() ) |
| 357 | ResumeThread( hThread ); | 357 | ResumeThread( hThread ); |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | void StackTrace(HANDLE hThread, const char* lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp ) | 360 | void StackTrace(HANDLE hThread, const char* lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp ) |
| 361 | { | 361 | { |
| 362 | STACKFRAME callStack; | 362 | STACKFRAME callStack; |
| 363 | BOOL bResult; | 363 | BOOL bResult; |
| 364 | TCHAR symInfo[BUFFERSIZE] = _T("?"); | 364 | TCHAR symInfo[BUFFERSIZE] = _T("?"); |
| 365 | TCHAR srcInfo[BUFFERSIZE] = _T("?"); | 365 | TCHAR srcInfo[BUFFERSIZE] = _T("?"); |
| 366 | HANDLE hProcess = GetCurrentProcess(); | 366 | HANDLE hProcess = GetCurrentProcess(); |
| 367 | 367 | ||
| 368 | // If it's not this thread, let's suspend it, and resume it at the end | 368 | // If it's not this thread, let's suspend it, and resume it at the end |
| 369 | if ( hThread != GetCurrentThread() ) | 369 | if ( hThread != GetCurrentThread() ) |
| 370 | if ( SuspendThread( hThread ) == -1 ) | 370 | if ( SuspendThread( hThread ) == -1 ) |
| 371 | { | 371 | { |
| 372 | // whaaat ?! | 372 | // whaaat ?! |
| 373 | etfprint(file, "Call stack info failed\n"); | 373 | etfprint(file, "Call stack info failed\n"); |
| 374 | return; | 374 | return; |
| 375 | } | 375 | } |
| 376 | 376 | ||
| 377 | ::ZeroMemory( &callStack, sizeof(callStack) ); | 377 | ::ZeroMemory( &callStack, sizeof(callStack) ); |
| 378 | callStack.AddrPC.Offset = eip; | 378 | callStack.AddrPC.Offset = eip; |
| 379 | callStack.AddrStack.Offset = esp; | 379 | callStack.AddrStack.Offset = esp; |
| 380 | callStack.AddrFrame.Offset = ebp; | 380 | callStack.AddrFrame.Offset = ebp; |
| 381 | callStack.AddrPC.Mode = AddrModeFlat; | 381 | callStack.AddrPC.Mode = AddrModeFlat; |
| 382 | callStack.AddrStack.Mode = AddrModeFlat; | 382 | callStack.AddrStack.Mode = AddrModeFlat; |
| 383 | callStack.AddrFrame.Mode = AddrModeFlat; | 383 | callStack.AddrFrame.Mode = AddrModeFlat; |
| 384 | 384 | ||
| 385 | etfprint(file, "Call stack info: \n"); | 385 | etfprint(file, "Call stack info: \n"); |
| 386 | etfprint(file, lpszMessage); | 386 | etfprint(file, lpszMessage); |
| 387 | 387 | ||
| 388 | PrintFunctionAndSourceInfo(file, callStack); | 388 | PrintFunctionAndSourceInfo(file, callStack); |
| 389 | 389 | ||
| 390 | for( ULONG index = 0; ; index++ ) | 390 | for( ULONG index = 0; ; index++ ) |
| 391 | { | 391 | { |
| 392 | bResult = StackWalk( | 392 | bResult = StackWalk( |
| 393 | IMAGE_FILE_MACHINE_I386, | 393 | IMAGE_FILE_MACHINE_I386, |
| 394 | hProcess, | 394 | hProcess, |
| 395 | hThread, | 395 | hThread, |
| 396 | &callStack, | 396 | &callStack, |
| 397 | NULL, | 397 | NULL, |
| 398 | NULL, | 398 | NULL, |
| 399 | SymFunctionTableAccess, | 399 | SymFunctionTableAccess, |
| 400 | SymGetModuleBase, | 400 | SymGetModuleBase, |
| 401 | NULL); | 401 | NULL); |
| 402 | 402 | ||
| 403 | if ( index == 0 ) | 403 | if ( index == 0 ) |
| 404 | continue; | 404 | continue; |
| 405 | 405 | ||
| 406 | if( !bResult || callStack.AddrFrame.Offset == 0 ) | 406 | if( !bResult || callStack.AddrFrame.Offset == 0 ) |
| 407 | break; | 407 | break; |
| 408 | 408 | ||
| 409 | PrintFunctionAndSourceInfo(file, callStack); | 409 | PrintFunctionAndSourceInfo(file, callStack); |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | if ( hThread != GetCurrentThread() ) | 412 | if ( hThread != GetCurrentThread() ) |
| 413 | ResumeThread( hThread ); | 413 | ResumeThread( hThread ); |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | char g_uefbuf[2048]; | 416 | char g_uefbuf[2048]; |
| 417 | 417 | ||
| 418 | void etfprintf(FILE *file, const char *format, ...) | 418 | void etfprintf(FILE *file, const char *format, ...) |
| 419 | { | 419 | { |
| 420 | va_list ap; | 420 | va_list ap; |
| 421 | va_start(ap, format); | 421 | va_start(ap, format); |
| 422 | int len = vsprintf(g_uefbuf, format, ap); | 422 | int len = vsprintf(g_uefbuf, format, ap); |
| 423 | fwrite(g_uefbuf, 1, len, file); | 423 | fwrite(g_uefbuf, 1, len, file); |
| 424 | va_end(ap); | 424 | va_end(ap); |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | void etfprint(FILE *file, const std::string &text) | 427 | void etfprint(FILE *file, const std::string &text) |
| 428 | { | 428 | { |
| 429 | size_t len = text.length(); | 429 | size_t len = text.length(); |
| 430 | fwrite(text.data(), 1, len, file); | 430 | fwrite(text.data(), 1, len, file); |
| 431 | } | 431 | } |
| 432 | 432 | ||
| 433 | #endif //WIN32 | 433 | #endif //WIN32 |
diff --git a/src/common/src/extended_trace.h b/src/common/src/extended_trace.h index 6d33eb632..1552e901b 100644 --- a/src/common/src/extended_trace.h +++ b/src/common/src/extended_trace.h | |||
| @@ -24,9 +24,9 @@ | |||
| 24 | 24 | ||
| 25 | #pragma comment( lib, "imagehlp.lib" ) | 25 | #pragma comment( lib, "imagehlp.lib" ) |
| 26 | 26 | ||
| 27 | #define EXTENDEDTRACEINITIALIZE( IniSymbolPath ) InitSymInfo( IniSymbolPath ) | 27 | #define EXTENDEDTRACEINITIALIZE( IniSymbolPath ) InitSymInfo( IniSymbolPath ) |
| 28 | #define EXTENDEDTRACEUNINITIALIZE() UninitSymInfo() | 28 | #define EXTENDEDTRACEUNINITIALIZE() UninitSymInfo() |
| 29 | #define STACKTRACE(file) StackTrace( GetCurrentThread(), "", file) | 29 | #define STACKTRACE(file) StackTrace( GetCurrentThread(), "", file) |
| 30 | #define STACKTRACE2(file, eip, esp, ebp) StackTrace(GetCurrentThread(), "", file, eip, esp, ebp) | 30 | #define STACKTRACE2(file, eip, esp, ebp) StackTrace(GetCurrentThread(), "", file, eip, esp, ebp) |
| 31 | // class File; | 31 | // class File; |
| 32 | 32 | ||
| @@ -41,13 +41,13 @@ void etfprint(FILE *file, const std::string &text); | |||
| 41 | #define UEFBUFSIZE 2048 | 41 | #define UEFBUFSIZE 2048 |
| 42 | extern char g_uefbuf[UEFBUFSIZE]; | 42 | extern char g_uefbuf[UEFBUFSIZE]; |
| 43 | 43 | ||
| 44 | #else // not WIN32 | 44 | #else // not WIN32 |
| 45 | 45 | ||
| 46 | #define EXTENDEDTRACEINITIALIZE( IniSymbolPath ) ((void)0) | 46 | #define EXTENDEDTRACEINITIALIZE( IniSymbolPath ) ((void)0) |
| 47 | #define EXTENDEDTRACEUNINITIALIZE() ((void)0) | 47 | #define EXTENDEDTRACEUNINITIALIZE() ((void)0) |
| 48 | #define STACKTRACE(file) ((void)0) | 48 | #define STACKTRACE(file) ((void)0) |
| 49 | #define STACKTRACE2(file, eip, esp, ebp) ((void)0) | 49 | #define STACKTRACE2(file, eip, esp, ebp) ((void)0) |
| 50 | 50 | ||
| 51 | #endif // WIN32 | 51 | #endif // WIN32 |
| 52 | 52 | ||
| 53 | #endif // _EXTENDEDTRACE_H_INCLUDED_ | 53 | #endif // _EXTENDEDTRACE_H_INCLUDED_ |
diff --git a/src/common/src/fifo_queue.h b/src/common/src/fifo_queue.h index 4f5ca5706..57efcd839 100644 --- a/src/common/src/fifo_queue.h +++ b/src/common/src/fifo_queue.h | |||
| @@ -14,100 +14,100 @@ template <typename T> | |||
| 14 | class FifoQueue | 14 | class FifoQueue |
| 15 | { | 15 | { |
| 16 | public: | 16 | public: |
| 17 | FifoQueue() : m_size(0) | 17 | FifoQueue() : m_size(0) |
| 18 | { | 18 | { |
| 19 | m_write_ptr = m_read_ptr = new ElementPtr(); | 19 | m_write_ptr = m_read_ptr = new ElementPtr(); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | ~FifoQueue() | 22 | ~FifoQueue() |
| 23 | { | 23 | { |
| 24 | // this will empty out the whole queue | 24 | // this will empty out the whole queue |
| 25 | delete m_read_ptr; | 25 | delete m_read_ptr; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | u32 Size() const | 28 | u32 Size() const |
| 29 | { | 29 | { |
| 30 | return m_size; | 30 | return m_size; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | bool Empty() const | 33 | bool Empty() const |
| 34 | { | 34 | { |
| 35 | //return (m_read_ptr == m_write_ptr); | 35 | //return (m_read_ptr == m_write_ptr); |
| 36 | return (0 == m_size); | 36 | return (0 == m_size); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | T& Front() const | 39 | T& Front() const |
| 40 | { | 40 | { |
| 41 | return *m_read_ptr->current; | 41 | return *m_read_ptr->current; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | template <typename Arg> | 44 | template <typename Arg> |
| 45 | void Push(Arg&& t) | 45 | void Push(Arg&& t) |
| 46 | { | 46 | { |
| 47 | // create the element, add it to the queue | 47 | // create the element, add it to the queue |
| 48 | m_write_ptr->current = new T(std::forward<Arg>(t)); | 48 | m_write_ptr->current = new T(std::forward<Arg>(t)); |
| 49 | // set the next pointer to a new element ptr | 49 | // set the next pointer to a new element ptr |
| 50 | // then advance the write pointer | 50 | // then advance the write pointer |
| 51 | m_write_ptr = m_write_ptr->next = new ElementPtr(); | 51 | m_write_ptr = m_write_ptr->next = new ElementPtr(); |
| 52 | Common::AtomicIncrement(m_size); | 52 | Common::AtomicIncrement(m_size); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | void Pop() | 55 | void Pop() |
| 56 | { | 56 | { |
| 57 | Common::AtomicDecrement(m_size); | 57 | Common::AtomicDecrement(m_size); |
| 58 | ElementPtr *const tmpptr = m_read_ptr; | 58 | ElementPtr *const tmpptr = m_read_ptr; |
| 59 | // advance the read pointer | 59 | // advance the read pointer |
| 60 | m_read_ptr = m_read_ptr->next; | 60 | m_read_ptr = m_read_ptr->next; |
| 61 | // set the next element to NULL to stop the recursive deletion | 61 | // set the next element to NULL to stop the recursive deletion |
| 62 | tmpptr->next = NULL; | 62 | tmpptr->next = NULL; |
| 63 | delete tmpptr; // this also deletes the element | 63 | delete tmpptr; // this also deletes the element |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | bool Pop(T& t) | 66 | bool Pop(T& t) |
| 67 | { | 67 | { |
| 68 | if (Empty()) | 68 | if (Empty()) |
| 69 | return false; | 69 | return false; |
| 70 | 70 | ||
| 71 | t = std::move(Front()); | 71 | t = std::move(Front()); |
| 72 | Pop(); | 72 | Pop(); |
| 73 | 73 | ||
| 74 | return true; | 74 | return true; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | // not thread-safe | 77 | // not thread-safe |
| 78 | void Clear() | 78 | void Clear() |
| 79 | { | 79 | { |
| 80 | m_size = 0; | 80 | m_size = 0; |
| 81 | delete m_read_ptr; | 81 | delete m_read_ptr; |
| 82 | m_write_ptr = m_read_ptr = new ElementPtr(); | 82 | m_write_ptr = m_read_ptr = new ElementPtr(); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | private: | 85 | private: |
| 86 | // stores a pointer to element | 86 | // stores a pointer to element |
| 87 | // and a pointer to the next ElementPtr | 87 | // and a pointer to the next ElementPtr |
| 88 | class ElementPtr | 88 | class ElementPtr |
| 89 | { | 89 | { |
| 90 | public: | 90 | public: |
| 91 | ElementPtr() : current(NULL), next(NULL) {} | 91 | ElementPtr() : current(NULL), next(NULL) {} |
| 92 | 92 | ||
| 93 | ~ElementPtr() | 93 | ~ElementPtr() |
| 94 | { | 94 | { |
| 95 | if (current) | 95 | if (current) |
| 96 | { | 96 | { |
| 97 | delete current; | 97 | delete current; |
| 98 | // recusion ftw | 98 | // recusion ftw |
| 99 | if (next) | 99 | if (next) |
| 100 | delete next; | 100 | delete next; |
| 101 | } | 101 | } |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | T *volatile current; | 104 | T *volatile current; |
| 105 | ElementPtr *volatile next; | 105 | ElementPtr *volatile next; |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | ElementPtr *volatile m_write_ptr; | 108 | ElementPtr *volatile m_write_ptr; |
| 109 | ElementPtr *volatile m_read_ptr; | 109 | ElementPtr *volatile m_read_ptr; |
| 110 | volatile u32 m_size; | 110 | volatile u32 m_size; |
| 111 | }; | 111 | }; |
| 112 | 112 | ||
| 113 | } | 113 | } |
diff --git a/src/common/src/file_search.cpp b/src/common/src/file_search.cpp index ba140ec12..59f640109 100644 --- a/src/common/src/file_search.cpp +++ b/src/common/src/file_search.cpp | |||
| @@ -22,85 +22,85 @@ | |||
| 22 | 22 | ||
| 23 | CFileSearch::CFileSearch(const CFileSearch::XStringVector& _rSearchStrings, const CFileSearch::XStringVector& _rDirectories) | 23 | CFileSearch::CFileSearch(const CFileSearch::XStringVector& _rSearchStrings, const CFileSearch::XStringVector& _rDirectories) |
| 24 | { | 24 | { |
| 25 | // Reverse the loop order for speed? | 25 | // Reverse the loop order for speed? |
| 26 | for (size_t j = 0; j < _rSearchStrings.size(); j++) | 26 | for (size_t j = 0; j < _rSearchStrings.size(); j++) |
| 27 | { | 27 | { |
| 28 | for (size_t i = 0; i < _rDirectories.size(); i++) | 28 | for (size_t i = 0; i < _rDirectories.size(); i++) |
| 29 | { | 29 | { |
| 30 | FindFiles(_rSearchStrings[j], _rDirectories[i]); | 30 | FindFiles(_rSearchStrings[j], _rDirectories[i]); |
| 31 | } | 31 | } |
| 32 | } | 32 | } |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | 35 | ||
| 36 | void CFileSearch::FindFiles(const std::string& _searchString, const std::string& _strPath) | 36 | void CFileSearch::FindFiles(const std::string& _searchString, const std::string& _strPath) |
| 37 | { | 37 | { |
| 38 | std::string GCMSearchPath; | 38 | std::string GCMSearchPath; |
| 39 | BuildCompleteFilename(GCMSearchPath, _strPath, _searchString); | 39 | BuildCompleteFilename(GCMSearchPath, _strPath, _searchString); |
| 40 | #ifdef _WIN32 | 40 | #ifdef _WIN32 |
| 41 | WIN32_FIND_DATA findData; | 41 | WIN32_FIND_DATA findData; |
| 42 | HANDLE FindFirst = FindFirstFile(UTF8ToTStr(GCMSearchPath).c_str(), &findData); | 42 | HANDLE FindFirst = FindFirstFile(UTF8ToTStr(GCMSearchPath).c_str(), &findData); |
| 43 | 43 | ||
| 44 | if (FindFirst != INVALID_HANDLE_VALUE) | 44 | if (FindFirst != INVALID_HANDLE_VALUE) |
| 45 | { | 45 | { |
| 46 | bool bkeepLooping = true; | 46 | bool bkeepLooping = true; |
| 47 | 47 | ||
| 48 | while (bkeepLooping) | 48 | while (bkeepLooping) |
| 49 | { | 49 | { |
| 50 | if (findData.cFileName[0] != '.') | 50 | if (findData.cFileName[0] != '.') |
| 51 | { | 51 | { |
| 52 | std::string strFilename; | 52 | std::string strFilename; |
| 53 | BuildCompleteFilename(strFilename, _strPath, TStrToUTF8(findData.cFileName)); | 53 | BuildCompleteFilename(strFilename, _strPath, TStrToUTF8(findData.cFileName)); |
| 54 | m_FileNames.push_back(strFilename); | 54 | m_FileNames.push_back(strFilename); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | bkeepLooping = FindNextFile(FindFirst, &findData) ? true : false; | 57 | bkeepLooping = FindNextFile(FindFirst, &findData) ? true : false; |
| 58 | } | 58 | } |
| 59 | } | 59 | } |
| 60 | FindClose(FindFirst); | 60 | FindClose(FindFirst); |
| 61 | 61 | ||
| 62 | 62 | ||
| 63 | #else | 63 | #else |
| 64 | // TODO: super lame/broken | 64 | // TODO: super lame/broken |
| 65 | 65 | ||
| 66 | auto end_match(_searchString); | 66 | auto end_match(_searchString); |
| 67 | 67 | ||
| 68 | // assuming we have a "*.blah"-like pattern | 68 | // assuming we have a "*.blah"-like pattern |
| 69 | if (!end_match.empty() && end_match[0] == '*') | 69 | if (!end_match.empty() && end_match[0] == '*') |
| 70 | end_match.erase(0, 1); | 70 | end_match.erase(0, 1); |
| 71 | 71 | ||
| 72 | // ugly | 72 | // ugly |
| 73 | if (end_match == ".*") | 73 | if (end_match == ".*") |
| 74 | end_match.clear(); | 74 | end_match.clear(); |
| 75 | 75 | ||
| 76 | DIR* dir = opendir(_strPath.c_str()); | 76 | DIR* dir = opendir(_strPath.c_str()); |
| 77 | 77 | ||
| 78 | if (!dir) | 78 | if (!dir) |
| 79 | return; | 79 | return; |
| 80 | 80 | ||
| 81 | while (auto const dp = readdir(dir)) | 81 | while (auto const dp = readdir(dir)) |
| 82 | { | 82 | { |
| 83 | std::string found(dp->d_name); | 83 | std::string found(dp->d_name); |
| 84 | 84 | ||
| 85 | if ((found != ".") && (found != "..") | 85 | if ((found != ".") && (found != "..") |
| 86 | && (found.size() >= end_match.size()) | 86 | && (found.size() >= end_match.size()) |
| 87 | && std::equal(end_match.rbegin(), end_match.rend(), found.rbegin())) | 87 | && std::equal(end_match.rbegin(), end_match.rend(), found.rbegin())) |
| 88 | { | 88 | { |
| 89 | std::string full_name; | 89 | std::string full_name; |
| 90 | if (_strPath.c_str()[_strPath.size()-1] == DIR_SEP_CHR) | 90 | if (_strPath.c_str()[_strPath.size()-1] == DIR_SEP_CHR) |
| 91 | full_name = _strPath + found; | 91 | full_name = _strPath + found; |
| 92 | else | 92 | else |
| 93 | full_name = _strPath + DIR_SEP + found; | 93 | full_name = _strPath + DIR_SEP + found; |
| 94 | 94 | ||
| 95 | m_FileNames.push_back(full_name); | 95 | m_FileNames.push_back(full_name); |
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | closedir(dir); | 99 | closedir(dir); |
| 100 | #endif | 100 | #endif |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | const CFileSearch::XStringVector& CFileSearch::GetFileNames() const | 103 | const CFileSearch::XStringVector& CFileSearch::GetFileNames() const |
| 104 | { | 104 | { |
| 105 | return m_FileNames; | 105 | return m_FileNames; |
| 106 | } | 106 | } |
diff --git a/src/common/src/file_search.h b/src/common/src/file_search.h index 55aaf4ebe..2a9ff801f 100644 --- a/src/common/src/file_search.h +++ b/src/common/src/file_search.h | |||
| @@ -12,16 +12,16 @@ | |||
| 12 | class CFileSearch | 12 | class CFileSearch |
| 13 | { | 13 | { |
| 14 | public: | 14 | public: |
| 15 | typedef std::vector<std::string>XStringVector; | 15 | typedef std::vector<std::string>XStringVector; |
| 16 | 16 | ||
| 17 | CFileSearch(const XStringVector& _rSearchStrings, const XStringVector& _rDirectories); | 17 | CFileSearch(const XStringVector& _rSearchStrings, const XStringVector& _rDirectories); |
| 18 | const XStringVector& GetFileNames() const; | 18 | const XStringVector& GetFileNames() const; |
| 19 | 19 | ||
| 20 | private: | 20 | private: |
| 21 | 21 | ||
| 22 | void FindFiles(const std::string& _searchString, const std::string& _strPath); | 22 | void FindFiles(const std::string& _searchString, const std::string& _strPath); |
| 23 | 23 | ||
| 24 | XStringVector m_FileNames; | 24 | XStringVector m_FileNames; |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | #endif // _FILESEARCH_H_ | 27 | #endif // _FILESEARCH_H_ |
diff --git a/src/common/src/file_util.cpp b/src/common/src/file_util.cpp index 76927c3bc..8b47cb3e5 100644 --- a/src/common/src/file_util.cpp +++ b/src/common/src/file_util.cpp | |||
| @@ -10,11 +10,11 @@ | |||
| 10 | 10 | ||
| 11 | #ifdef _WIN32 | 11 | #ifdef _WIN32 |
| 12 | #include <windows.h> | 12 | #include <windows.h> |
| 13 | #include <shlobj.h> // for SHGetFolderPath | 13 | #include <shlobj.h> // for SHGetFolderPath |
| 14 | #include <shellapi.h> | 14 | #include <shellapi.h> |
| 15 | #include <commdlg.h> // for GetSaveFileName | 15 | #include <commdlg.h> // for GetSaveFileName |
| 16 | #include <io.h> | 16 | #include <io.h> |
| 17 | #include <direct.h> // getcwd | 17 | #include <direct.h> // getcwd |
| 18 | #else | 18 | #else |
| 19 | #include <sys/param.h> | 19 | #include <sys/param.h> |
| 20 | #include <sys/types.h> | 20 | #include <sys/types.h> |
| @@ -53,354 +53,354 @@ namespace File | |||
| 53 | // Modifies argument. | 53 | // Modifies argument. |
| 54 | static void StripTailDirSlashes(std::string &fname) | 54 | static void StripTailDirSlashes(std::string &fname) |
| 55 | { | 55 | { |
| 56 | if (fname.length() > 1) | 56 | if (fname.length() > 1) |
| 57 | { | 57 | { |
| 58 | size_t i = fname.length() - 1; | 58 | size_t i = fname.length() - 1; |
| 59 | while (fname[i] == DIR_SEP_CHR) | 59 | while (fname[i] == DIR_SEP_CHR) |
| 60 | fname[i--] = '\0'; | 60 | fname[i--] = '\0'; |
| 61 | } | 61 | } |
| 62 | return; | 62 | return; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | // Returns true if file filename exists | 65 | // Returns true if file filename exists |
| 66 | bool Exists(const std::string &filename) | 66 | bool Exists(const std::string &filename) |
| 67 | { | 67 | { |
| 68 | struct stat64 file_info; | 68 | struct stat64 file_info; |
| 69 | 69 | ||
| 70 | std::string copy(filename); | 70 | std::string copy(filename); |
| 71 | StripTailDirSlashes(copy); | 71 | StripTailDirSlashes(copy); |
| 72 | 72 | ||
| 73 | #ifdef _WIN32 | 73 | #ifdef _WIN32 |
| 74 | int result = _tstat64(UTF8ToTStr(copy).c_str(), &file_info); | 74 | int result = _tstat64(UTF8ToTStr(copy).c_str(), &file_info); |
| 75 | #else | 75 | #else |
| 76 | int result = stat64(copy.c_str(), &file_info); | 76 | int result = stat64(copy.c_str(), &file_info); |
| 77 | #endif | 77 | #endif |
| 78 | 78 | ||
| 79 | return (result == 0); | 79 | return (result == 0); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | // Returns true if filename is a directory | 82 | // Returns true if filename is a directory |
| 83 | bool IsDirectory(const std::string &filename) | 83 | bool IsDirectory(const std::string &filename) |
| 84 | { | 84 | { |
| 85 | struct stat64 file_info; | 85 | struct stat64 file_info; |
| 86 | 86 | ||
| 87 | std::string copy(filename); | 87 | std::string copy(filename); |
| 88 | StripTailDirSlashes(copy); | 88 | StripTailDirSlashes(copy); |
| 89 | 89 | ||
| 90 | #ifdef _WIN32 | 90 | #ifdef _WIN32 |
| 91 | int result = _tstat64(UTF8ToTStr(copy).c_str(), &file_info); | 91 | int result = _tstat64(UTF8ToTStr(copy).c_str(), &file_info); |
| 92 | #else | 92 | #else |
| 93 | int result = stat64(copy.c_str(), &file_info); | 93 | int result = stat64(copy.c_str(), &file_info); |
| 94 | #endif | 94 | #endif |
| 95 | 95 | ||
| 96 | if (result < 0) { | 96 | if (result < 0) { |
| 97 | WARN_LOG(COMMON, "IsDirectory: stat failed on %s: %s", | 97 | WARN_LOG(COMMON, "IsDirectory: stat failed on %s: %s", |
| 98 | filename.c_str(), GetLastErrorMsg()); | 98 | filename.c_str(), GetLastErrorMsg()); |
| 99 | return false; | 99 | return false; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | return S_ISDIR(file_info.st_mode); | 102 | return S_ISDIR(file_info.st_mode); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | // Deletes a given filename, return true on success | 105 | // Deletes a given filename, return true on success |
| 106 | // Doesn't supports deleting a directory | 106 | // Doesn't supports deleting a directory |
| 107 | bool Delete(const std::string &filename) | 107 | bool Delete(const std::string &filename) |
| 108 | { | 108 | { |
| 109 | INFO_LOG(COMMON, "Delete: file %s", filename.c_str()); | 109 | INFO_LOG(COMMON, "Delete: file %s", filename.c_str()); |
| 110 | 110 | ||
| 111 | // Return true because we care about the file no | 111 | // Return true because we care about the file no |
| 112 | // being there, not the actual delete. | 112 | // being there, not the actual delete. |
| 113 | if (!Exists(filename)) | 113 | if (!Exists(filename)) |
| 114 | { | 114 | { |
| 115 | WARN_LOG(COMMON, "Delete: %s does not exist", filename.c_str()); | 115 | WARN_LOG(COMMON, "Delete: %s does not exist", filename.c_str()); |
| 116 | return true; | 116 | return true; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | // We can't delete a directory | 119 | // We can't delete a directory |
| 120 | if (IsDirectory(filename)) | 120 | if (IsDirectory(filename)) |
| 121 | { | 121 | { |
| 122 | WARN_LOG(COMMON, "Delete failed: %s is a directory", filename.c_str()); | 122 | WARN_LOG(COMMON, "Delete failed: %s is a directory", filename.c_str()); |
| 123 | return false; | 123 | return false; |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | #ifdef _WIN32 | 126 | #ifdef _WIN32 |
| 127 | if (!DeleteFile(UTF8ToTStr(filename).c_str())) | 127 | if (!DeleteFile(UTF8ToTStr(filename).c_str())) |
| 128 | { | 128 | { |
| 129 | WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s", | 129 | WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s", |
| 130 | filename.c_str(), GetLastErrorMsg()); | 130 | filename.c_str(), GetLastErrorMsg()); |
| 131 | return false; | 131 | return false; |
| 132 | } | 132 | } |
| 133 | #else | 133 | #else |
| 134 | if (unlink(filename.c_str()) == -1) { | 134 | if (unlink(filename.c_str()) == -1) { |
| 135 | WARN_LOG(COMMON, "Delete: unlink failed on %s: %s", | 135 | WARN_LOG(COMMON, "Delete: unlink failed on %s: %s", |
| 136 | filename.c_str(), GetLastErrorMsg()); | 136 | filename.c_str(), GetLastErrorMsg()); |
| 137 | return false; | 137 | return false; |
| 138 | } | 138 | } |
| 139 | #endif | 139 | #endif |
| 140 | 140 | ||
| 141 | return true; | 141 | return true; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | // Returns true if successful, or path already exists. | 144 | // Returns true if successful, or path already exists. |
| 145 | bool CreateDir(const std::string &path) | 145 | bool CreateDir(const std::string &path) |
| 146 | { | 146 | { |
| 147 | INFO_LOG(COMMON, "CreateDir: directory %s", path.c_str()); | 147 | INFO_LOG(COMMON, "CreateDir: directory %s", path.c_str()); |
| 148 | #ifdef _WIN32 | 148 | #ifdef _WIN32 |
| 149 | if (::CreateDirectory(UTF8ToTStr(path).c_str(), NULL)) | 149 | if (::CreateDirectory(UTF8ToTStr(path).c_str(), NULL)) |
| 150 | return true; | 150 | return true; |
| 151 | DWORD error = GetLastError(); | 151 | DWORD error = GetLastError(); |
| 152 | if (error == ERROR_ALREADY_EXISTS) | 152 | if (error == ERROR_ALREADY_EXISTS) |
| 153 | { | 153 | { |
| 154 | WARN_LOG(COMMON, "CreateDir: CreateDirectory failed on %s: already exists", path.c_str()); | 154 | WARN_LOG(COMMON, "CreateDir: CreateDirectory failed on %s: already exists", path.c_str()); |
| 155 | return true; | 155 | return true; |
| 156 | } | 156 | } |
| 157 | ERROR_LOG(COMMON, "CreateDir: CreateDirectory failed on %s: %i", path.c_str(), error); | 157 | ERROR_LOG(COMMON, "CreateDir: CreateDirectory failed on %s: %i", path.c_str(), error); |
| 158 | return false; | 158 | return false; |
| 159 | #else | 159 | #else |
| 160 | if (mkdir(path.c_str(), 0755) == 0) | 160 | if (mkdir(path.c_str(), 0755) == 0) |
| 161 | return true; | 161 | return true; |
| 162 | 162 | ||
| 163 | int err = errno; | 163 | int err = errno; |
| 164 | 164 | ||
| 165 | if (err == EEXIST) | 165 | if (err == EEXIST) |
| 166 | { | 166 | { |
| 167 | WARN_LOG(COMMON, "CreateDir: mkdir failed on %s: already exists", path.c_str()); | 167 | WARN_LOG(COMMON, "CreateDir: mkdir failed on %s: already exists", path.c_str()); |
| 168 | return true; | 168 | return true; |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | ERROR_LOG(COMMON, "CreateDir: mkdir failed on %s: %s", path.c_str(), strerror(err)); | 171 | ERROR_LOG(COMMON, "CreateDir: mkdir failed on %s: %s", path.c_str(), strerror(err)); |
| 172 | return false; | 172 | return false; |
| 173 | #endif | 173 | #endif |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | // Creates the full path of fullPath returns true on success | 176 | // Creates the full path of fullPath returns true on success |
| 177 | bool CreateFullPath(const std::string &fullPath) | 177 | bool CreateFullPath(const std::string &fullPath) |
| 178 | { | 178 | { |
| 179 | int panicCounter = 100; | 179 | int panicCounter = 100; |
| 180 | INFO_LOG(COMMON, "CreateFullPath: path %s", fullPath.c_str()); | 180 | INFO_LOG(COMMON, "CreateFullPath: path %s", fullPath.c_str()); |
| 181 | 181 | ||
| 182 | if (File::Exists(fullPath)) | 182 | if (File::Exists(fullPath)) |
| 183 | { | 183 | { |
| 184 | INFO_LOG(COMMON, "CreateFullPath: path exists %s", fullPath.c_str()); | 184 | INFO_LOG(COMMON, "CreateFullPath: path exists %s", fullPath.c_str()); |
| 185 | return true; | 185 | return true; |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | size_t position = 0; | 188 | size_t position = 0; |
| 189 | while (true) | 189 | while (true) |
| 190 | { | 190 | { |
| 191 | // Find next sub path | 191 | // Find next sub path |
| 192 | position = fullPath.find(DIR_SEP_CHR, position); | 192 | position = fullPath.find(DIR_SEP_CHR, position); |
| 193 | 193 | ||
| 194 | // we're done, yay! | 194 | // we're done, yay! |
| 195 | if (position == fullPath.npos) | 195 | if (position == fullPath.npos) |
| 196 | return true; | 196 | return true; |
| 197 | 197 | ||
| 198 | // Include the '/' so the first call is CreateDir("/") rather than CreateDir("") | 198 | // Include the '/' so the first call is CreateDir("/") rather than CreateDir("") |
| 199 | std::string const subPath(fullPath.substr(0, position + 1)); | 199 | std::string const subPath(fullPath.substr(0, position + 1)); |
| 200 | if (!File::IsDirectory(subPath)) | 200 | if (!File::IsDirectory(subPath)) |
| 201 | File::CreateDir(subPath); | 201 | File::CreateDir(subPath); |
| 202 | 202 | ||
| 203 | // A safety check | 203 | // A safety check |
| 204 | panicCounter--; | 204 | panicCounter--; |
| 205 | if (panicCounter <= 0) | 205 | if (panicCounter <= 0) |
| 206 | { | 206 | { |
| 207 | ERROR_LOG(COMMON, "CreateFullPath: directory structure is too deep"); | 207 | ERROR_LOG(COMMON, "CreateFullPath: directory structure is too deep"); |
| 208 | return false; | 208 | return false; |
| 209 | } | 209 | } |
| 210 | position++; | 210 | position++; |
| 211 | } | 211 | } |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | 214 | ||
| 215 | // Deletes a directory filename, returns true on success | 215 | // Deletes a directory filename, returns true on success |
| 216 | bool DeleteDir(const std::string &filename) | 216 | bool DeleteDir(const std::string &filename) |
| 217 | { | 217 | { |
| 218 | INFO_LOG(COMMON, "DeleteDir: directory %s", filename.c_str()); | 218 | INFO_LOG(COMMON, "DeleteDir: directory %s", filename.c_str()); |
| 219 | 219 | ||
| 220 | // check if a directory | 220 | // check if a directory |
| 221 | if (!File::IsDirectory(filename)) | 221 | if (!File::IsDirectory(filename)) |
| 222 | { | 222 | { |
| 223 | ERROR_LOG(COMMON, "DeleteDir: Not a directory %s", filename.c_str()); | 223 | ERROR_LOG(COMMON, "DeleteDir: Not a directory %s", filename.c_str()); |
| 224 | return false; | 224 | return false; |
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | #ifdef _WIN32 | 227 | #ifdef _WIN32 |
| 228 | if (::RemoveDirectory(UTF8ToTStr(filename).c_str())) | 228 | if (::RemoveDirectory(UTF8ToTStr(filename).c_str())) |
| 229 | return true; | 229 | return true; |
| 230 | #else | 230 | #else |
| 231 | if (rmdir(filename.c_str()) == 0) | 231 | if (rmdir(filename.c_str()) == 0) |
| 232 | return true; | 232 | return true; |
| 233 | #endif | 233 | #endif |
| 234 | ERROR_LOG(COMMON, "DeleteDir: %s: %s", filename.c_str(), GetLastErrorMsg()); | 234 | ERROR_LOG(COMMON, "DeleteDir: %s: %s", filename.c_str(), GetLastErrorMsg()); |
| 235 | 235 | ||
| 236 | return false; | 236 | return false; |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | // renames file srcFilename to destFilename, returns true on success | 239 | // renames file srcFilename to destFilename, returns true on success |
| 240 | bool Rename(const std::string &srcFilename, const std::string &destFilename) | 240 | bool Rename(const std::string &srcFilename, const std::string &destFilename) |
| 241 | { | 241 | { |
| 242 | INFO_LOG(COMMON, "Rename: %s --> %s", | 242 | INFO_LOG(COMMON, "Rename: %s --> %s", |
| 243 | srcFilename.c_str(), destFilename.c_str()); | 243 | srcFilename.c_str(), destFilename.c_str()); |
| 244 | if (rename(srcFilename.c_str(), destFilename.c_str()) == 0) | 244 | if (rename(srcFilename.c_str(), destFilename.c_str()) == 0) |
| 245 | return true; | 245 | return true; |
| 246 | ERROR_LOG(COMMON, "Rename: failed %s --> %s: %s", | 246 | ERROR_LOG(COMMON, "Rename: failed %s --> %s: %s", |
| 247 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 247 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 248 | return false; | 248 | return false; |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | // copies file srcFilename to destFilename, returns true on success | 251 | // copies file srcFilename to destFilename, returns true on success |
| 252 | bool Copy(const std::string &srcFilename, const std::string &destFilename) | 252 | bool Copy(const std::string &srcFilename, const std::string &destFilename) |
| 253 | { | 253 | { |
| 254 | INFO_LOG(COMMON, "Copy: %s --> %s", | 254 | INFO_LOG(COMMON, "Copy: %s --> %s", |
| 255 | srcFilename.c_str(), destFilename.c_str()); | 255 | srcFilename.c_str(), destFilename.c_str()); |
| 256 | #ifdef _WIN32 | 256 | #ifdef _WIN32 |
| 257 | if (CopyFile(UTF8ToTStr(srcFilename).c_str(), UTF8ToTStr(destFilename).c_str(), FALSE)) | 257 | if (CopyFile(UTF8ToTStr(srcFilename).c_str(), UTF8ToTStr(destFilename).c_str(), FALSE)) |
| 258 | return true; | 258 | return true; |
| 259 | 259 | ||
| 260 | ERROR_LOG(COMMON, "Copy: failed %s --> %s: %s", | 260 | ERROR_LOG(COMMON, "Copy: failed %s --> %s: %s", |
| 261 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 261 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 262 | return false; | 262 | return false; |
| 263 | #else | 263 | #else |
| 264 | 264 | ||
| 265 | // buffer size | 265 | // buffer size |
| 266 | #define BSIZE 1024 | 266 | #define BSIZE 1024 |
| 267 | 267 | ||
| 268 | char buffer[BSIZE]; | 268 | char buffer[BSIZE]; |
| 269 | 269 | ||
| 270 | // Open input file | 270 | // Open input file |
| 271 | FILE *input = fopen(srcFilename.c_str(), "rb"); | 271 | FILE *input = fopen(srcFilename.c_str(), "rb"); |
| 272 | if (!input) | 272 | if (!input) |
| 273 | { | 273 | { |
| 274 | ERROR_LOG(COMMON, "Copy: input failed %s --> %s: %s", | 274 | ERROR_LOG(COMMON, "Copy: input failed %s --> %s: %s", |
| 275 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 275 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 276 | return false; | 276 | return false; |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | // open output file | 279 | // open output file |
| 280 | FILE *output = fopen(destFilename.c_str(), "wb"); | 280 | FILE *output = fopen(destFilename.c_str(), "wb"); |
| 281 | if (!output) | 281 | if (!output) |
| 282 | { | 282 | { |
| 283 | fclose(input); | 283 | fclose(input); |
| 284 | ERROR_LOG(COMMON, "Copy: output failed %s --> %s: %s", | 284 | ERROR_LOG(COMMON, "Copy: output failed %s --> %s: %s", |
| 285 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 285 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 286 | return false; | 286 | return false; |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | // copy loop | 289 | // copy loop |
| 290 | while (!feof(input)) | 290 | while (!feof(input)) |
| 291 | { | 291 | { |
| 292 | // read input | 292 | // read input |
| 293 | int rnum = fread(buffer, sizeof(char), BSIZE, input); | 293 | int rnum = fread(buffer, sizeof(char), BSIZE, input); |
| 294 | if (rnum != BSIZE) | 294 | if (rnum != BSIZE) |
| 295 | { | 295 | { |
| 296 | if (ferror(input) != 0) | 296 | if (ferror(input) != 0) |
| 297 | { | 297 | { |
| 298 | ERROR_LOG(COMMON, | 298 | ERROR_LOG(COMMON, |
| 299 | "Copy: failed reading from source, %s --> %s: %s", | 299 | "Copy: failed reading from source, %s --> %s: %s", |
| 300 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 300 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 301 | goto bail; | 301 | goto bail; |
| 302 | } | 302 | } |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | // write output | 305 | // write output |
| 306 | int wnum = fwrite(buffer, sizeof(char), rnum, output); | 306 | int wnum = fwrite(buffer, sizeof(char), rnum, output); |
| 307 | if (wnum != rnum) | 307 | if (wnum != rnum) |
| 308 | { | 308 | { |
| 309 | ERROR_LOG(COMMON, | 309 | ERROR_LOG(COMMON, |
| 310 | "Copy: failed writing to output, %s --> %s: %s", | 310 | "Copy: failed writing to output, %s --> %s: %s", |
| 311 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 311 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 312 | goto bail; | 312 | goto bail; |
| 313 | } | 313 | } |
| 314 | } | 314 | } |
| 315 | // close files | 315 | // close files |
| 316 | fclose(input); | 316 | fclose(input); |
| 317 | fclose(output); | 317 | fclose(output); |
| 318 | return true; | 318 | return true; |
| 319 | bail: | 319 | bail: |
| 320 | if (input) | 320 | if (input) |
| 321 | fclose(input); | 321 | fclose(input); |
| 322 | if (output) | 322 | if (output) |
| 323 | fclose(output); | 323 | fclose(output); |
| 324 | return false; | 324 | return false; |
| 325 | #endif | 325 | #endif |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | // Returns the size of filename (64bit) | 328 | // Returns the size of filename (64bit) |
| 329 | u64 GetSize(const std::string &filename) | 329 | u64 GetSize(const std::string &filename) |
| 330 | { | 330 | { |
| 331 | if (!Exists(filename)) | 331 | if (!Exists(filename)) |
| 332 | { | 332 | { |
| 333 | WARN_LOG(COMMON, "GetSize: failed %s: No such file", filename.c_str()); | 333 | WARN_LOG(COMMON, "GetSize: failed %s: No such file", filename.c_str()); |
| 334 | return 0; | 334 | return 0; |
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | if (IsDirectory(filename)) | 337 | if (IsDirectory(filename)) |
| 338 | { | 338 | { |
| 339 | WARN_LOG(COMMON, "GetSize: failed %s: is a directory", filename.c_str()); | 339 | WARN_LOG(COMMON, "GetSize: failed %s: is a directory", filename.c_str()); |
| 340 | return 0; | 340 | return 0; |
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | struct stat64 buf; | 343 | struct stat64 buf; |
| 344 | #ifdef _WIN32 | 344 | #ifdef _WIN32 |
| 345 | if (_tstat64(UTF8ToTStr(filename).c_str(), &buf) == 0) | 345 | if (_tstat64(UTF8ToTStr(filename).c_str(), &buf) == 0) |
| 346 | #else | 346 | #else |
| 347 | if (stat64(filename.c_str(), &buf) == 0) | 347 | if (stat64(filename.c_str(), &buf) == 0) |
| 348 | #endif | 348 | #endif |
| 349 | { | 349 | { |
| 350 | DEBUG_LOG(COMMON, "GetSize: %s: %lld", | 350 | DEBUG_LOG(COMMON, "GetSize: %s: %lld", |
| 351 | filename.c_str(), (long long)buf.st_size); | 351 | filename.c_str(), (long long)buf.st_size); |
| 352 | return buf.st_size; | 352 | return buf.st_size; |
| 353 | } | 353 | } |
| 354 | 354 | ||
| 355 | ERROR_LOG(COMMON, "GetSize: Stat failed %s: %s", | 355 | ERROR_LOG(COMMON, "GetSize: Stat failed %s: %s", |
| 356 | filename.c_str(), GetLastErrorMsg()); | 356 | filename.c_str(), GetLastErrorMsg()); |
| 357 | return 0; | 357 | return 0; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | // Overloaded GetSize, accepts file descriptor | 360 | // Overloaded GetSize, accepts file descriptor |
| 361 | u64 GetSize(const int fd) | 361 | u64 GetSize(const int fd) |
| 362 | { | 362 | { |
| 363 | struct stat64 buf; | 363 | struct stat64 buf; |
| 364 | if (fstat64(fd, &buf) != 0) { | 364 | if (fstat64(fd, &buf) != 0) { |
| 365 | ERROR_LOG(COMMON, "GetSize: stat failed %i: %s", | 365 | ERROR_LOG(COMMON, "GetSize: stat failed %i: %s", |
| 366 | fd, GetLastErrorMsg()); | 366 | fd, GetLastErrorMsg()); |
| 367 | return 0; | 367 | return 0; |
| 368 | } | 368 | } |
| 369 | return buf.st_size; | 369 | return buf.st_size; |
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | // Overloaded GetSize, accepts FILE* | 372 | // Overloaded GetSize, accepts FILE* |
| 373 | u64 GetSize(FILE *f) | 373 | u64 GetSize(FILE *f) |
| 374 | { | 374 | { |
| 375 | // can't use off_t here because it can be 32-bit | 375 | // can't use off_t here because it can be 32-bit |
| 376 | u64 pos = ftello(f); | 376 | u64 pos = ftello(f); |
| 377 | if (fseeko(f, 0, SEEK_END) != 0) { | 377 | if (fseeko(f, 0, SEEK_END) != 0) { |
| 378 | ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", | 378 | ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", |
| 379 | f, GetLastErrorMsg()); | 379 | f, GetLastErrorMsg()); |
| 380 | return 0; | 380 | return 0; |
| 381 | } | 381 | } |
| 382 | u64 size = ftello(f); | 382 | u64 size = ftello(f); |
| 383 | if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) { | 383 | if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) { |
| 384 | ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", | 384 | ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", |
| 385 | f, GetLastErrorMsg()); | 385 | f, GetLastErrorMsg()); |
| 386 | return 0; | 386 | return 0; |
| 387 | } | 387 | } |
| 388 | return size; | 388 | return size; |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | // creates an empty file filename, returns true on success | 391 | // creates an empty file filename, returns true on success |
| 392 | bool CreateEmptyFile(const std::string &filename) | 392 | bool CreateEmptyFile(const std::string &filename) |
| 393 | { | 393 | { |
| 394 | INFO_LOG(COMMON, "CreateEmptyFile: %s", filename.c_str()); | 394 | INFO_LOG(COMMON, "CreateEmptyFile: %s", filename.c_str()); |
| 395 | 395 | ||
| 396 | if (!File::IOFile(filename, "wb")) | 396 | if (!File::IOFile(filename, "wb")) |
| 397 | { | 397 | { |
| 398 | ERROR_LOG(COMMON, "CreateEmptyFile: failed %s: %s", | 398 | ERROR_LOG(COMMON, "CreateEmptyFile: failed %s: %s", |
| 399 | filename.c_str(), GetLastErrorMsg()); | 399 | filename.c_str(), GetLastErrorMsg()); |
| 400 | return false; | 400 | return false; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | return true; | 403 | return true; |
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | 406 | ||
| @@ -408,503 +408,503 @@ bool CreateEmptyFile(const std::string &filename) | |||
| 408 | // results into parentEntry. Returns the number of files+directories found | 408 | // results into parentEntry. Returns the number of files+directories found |
| 409 | u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) | 409 | u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) |
| 410 | { | 410 | { |
| 411 | INFO_LOG(COMMON, "ScanDirectoryTree: directory %s", directory.c_str()); | 411 | INFO_LOG(COMMON, "ScanDirectoryTree: directory %s", directory.c_str()); |
| 412 | // How many files + directories we found | 412 | // How many files + directories we found |
| 413 | u32 foundEntries = 0; | 413 | u32 foundEntries = 0; |
| 414 | #ifdef _WIN32 | 414 | #ifdef _WIN32 |
| 415 | // Find the first file in the directory. | 415 | // Find the first file in the directory. |
| 416 | WIN32_FIND_DATA ffd; | 416 | WIN32_FIND_DATA ffd; |
| 417 | 417 | ||
| 418 | HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd); | 418 | HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd); |
| 419 | if (hFind == INVALID_HANDLE_VALUE) | 419 | if (hFind == INVALID_HANDLE_VALUE) |
| 420 | { | 420 | { |
| 421 | FindClose(hFind); | 421 | FindClose(hFind); |
| 422 | return foundEntries; | 422 | return foundEntries; |
| 423 | } | 423 | } |
| 424 | // windows loop | 424 | // windows loop |
| 425 | do | 425 | do |
| 426 | { | 426 | { |
| 427 | FSTEntry entry; | 427 | FSTEntry entry; |
| 428 | const std::string virtualName(TStrToUTF8(ffd.cFileName)); | 428 | const std::string virtualName(TStrToUTF8(ffd.cFileName)); |
| 429 | #else | 429 | #else |
| 430 | struct dirent dirent, *result = NULL; | 430 | struct dirent dirent, *result = NULL; |
| 431 | 431 | ||
| 432 | DIR *dirp = opendir(directory.c_str()); | 432 | DIR *dirp = opendir(directory.c_str()); |
| 433 | if (!dirp) | 433 | if (!dirp) |
| 434 | return 0; | 434 | return 0; |
| 435 | 435 | ||
| 436 | // non windows loop | 436 | // non windows loop |
| 437 | while (!readdir_r(dirp, &dirent, &result) && result) | 437 | while (!readdir_r(dirp, &dirent, &result) && result) |
| 438 | { | 438 | { |
| 439 | FSTEntry entry; | 439 | FSTEntry entry; |
| 440 | const std::string virtualName(result->d_name); | 440 | const std::string virtualName(result->d_name); |
| 441 | #endif | 441 | #endif |
| 442 | // check for "." and ".." | 442 | // check for "." and ".." |
| 443 | if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || | 443 | if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || |
| 444 | ((virtualName[0] == '.') && (virtualName[1] == '.') && | 444 | ((virtualName[0] == '.') && (virtualName[1] == '.') && |
| 445 | (virtualName[2] == '\0'))) | 445 | (virtualName[2] == '\0'))) |
| 446 | continue; | 446 | continue; |
| 447 | entry.virtualName = virtualName; | 447 | entry.virtualName = virtualName; |
| 448 | entry.physicalName = directory; | 448 | entry.physicalName = directory; |
| 449 | entry.physicalName += DIR_SEP + entry.virtualName; | 449 | entry.physicalName += DIR_SEP + entry.virtualName; |
| 450 | 450 | ||
| 451 | if (IsDirectory(entry.physicalName.c_str())) | 451 | if (IsDirectory(entry.physicalName.c_str())) |
| 452 | { | 452 | { |
| 453 | entry.isDirectory = true; | 453 | entry.isDirectory = true; |
| 454 | // is a directory, lets go inside | 454 | // is a directory, lets go inside |
| 455 | entry.size = ScanDirectoryTree(entry.physicalName, entry); | 455 | entry.size = ScanDirectoryTree(entry.physicalName, entry); |
| 456 | foundEntries += (u32)entry.size; | 456 | foundEntries += (u32)entry.size; |
| 457 | } | 457 | } |
| 458 | else | 458 | else |
| 459 | { // is a file | 459 | { // is a file |
| 460 | entry.isDirectory = false; | 460 | entry.isDirectory = false; |
| 461 | entry.size = GetSize(entry.physicalName.c_str()); | 461 | entry.size = GetSize(entry.physicalName.c_str()); |
| 462 | } | 462 | } |
| 463 | ++foundEntries; | 463 | ++foundEntries; |
| 464 | // Push into the tree | 464 | // Push into the tree |
| 465 | parentEntry.children.push_back(entry); | 465 | parentEntry.children.push_back(entry); |
| 466 | #ifdef _WIN32 | 466 | #ifdef _WIN32 |
| 467 | } while (FindNextFile(hFind, &ffd) != 0); | 467 | } while (FindNextFile(hFind, &ffd) != 0); |
| 468 | FindClose(hFind); | 468 | FindClose(hFind); |
| 469 | #else | 469 | #else |
| 470 | } | 470 | } |
| 471 | closedir(dirp); | 471 | closedir(dirp); |
| 472 | #endif | 472 | #endif |
| 473 | // Return number of entries found. | 473 | // Return number of entries found. |
| 474 | return foundEntries; | 474 | return foundEntries; |
| 475 | } | 475 | } |
| 476 | 476 | ||
| 477 | 477 | ||
| 478 | // Deletes the given directory and anything under it. Returns true on success. | 478 | // Deletes the given directory and anything under it. Returns true on success. |
| 479 | bool DeleteDirRecursively(const std::string &directory) | 479 | bool DeleteDirRecursively(const std::string &directory) |
| 480 | { | 480 | { |
| 481 | INFO_LOG(COMMON, "DeleteDirRecursively: %s", directory.c_str()); | 481 | INFO_LOG(COMMON, "DeleteDirRecursively: %s", directory.c_str()); |
| 482 | #ifdef _WIN32 | 482 | #ifdef _WIN32 |
| 483 | // Find the first file in the directory. | 483 | // Find the first file in the directory. |
| 484 | WIN32_FIND_DATA ffd; | 484 | WIN32_FIND_DATA ffd; |
| 485 | HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd); | 485 | HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd); |
| 486 | 486 | ||
| 487 | if (hFind == INVALID_HANDLE_VALUE) | 487 | if (hFind == INVALID_HANDLE_VALUE) |
| 488 | { | 488 | { |
| 489 | FindClose(hFind); | 489 | FindClose(hFind); |
| 490 | return false; | 490 | return false; |
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | // windows loop | 493 | // windows loop |
| 494 | do | 494 | do |
| 495 | { | 495 | { |
| 496 | const std::string virtualName(TStrToUTF8(ffd.cFileName)); | 496 | const std::string virtualName(TStrToUTF8(ffd.cFileName)); |
| 497 | #else | 497 | #else |
| 498 | struct dirent dirent, *result = NULL; | 498 | struct dirent dirent, *result = NULL; |
| 499 | DIR *dirp = opendir(directory.c_str()); | 499 | DIR *dirp = opendir(directory.c_str()); |
| 500 | if (!dirp) | 500 | if (!dirp) |
| 501 | return false; | 501 | return false; |
| 502 | 502 | ||
| 503 | // non windows loop | 503 | // non windows loop |
| 504 | while (!readdir_r(dirp, &dirent, &result) && result) | 504 | while (!readdir_r(dirp, &dirent, &result) && result) |
| 505 | { | 505 | { |
| 506 | const std::string virtualName = result->d_name; | 506 | const std::string virtualName = result->d_name; |
| 507 | #endif | 507 | #endif |
| 508 | 508 | ||
| 509 | // check for "." and ".." | 509 | // check for "." and ".." |
| 510 | if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || | 510 | if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || |
| 511 | ((virtualName[0] == '.') && (virtualName[1] == '.') && | 511 | ((virtualName[0] == '.') && (virtualName[1] == '.') && |
| 512 | (virtualName[2] == '\0'))) | 512 | (virtualName[2] == '\0'))) |
| 513 | continue; | 513 | continue; |
| 514 | 514 | ||
| 515 | std::string newPath = directory + DIR_SEP_CHR + virtualName; | 515 | std::string newPath = directory + DIR_SEP_CHR + virtualName; |
| 516 | if (IsDirectory(newPath)) | 516 | if (IsDirectory(newPath)) |
| 517 | { | 517 | { |
| 518 | if (!DeleteDirRecursively(newPath)) | 518 | if (!DeleteDirRecursively(newPath)) |
| 519 | { | 519 | { |
| 520 | #ifndef _WIN32 | 520 | #ifndef _WIN32 |
| 521 | closedir(dirp); | 521 | closedir(dirp); |
| 522 | #endif | 522 | #endif |
| 523 | 523 | ||
| 524 | return false; | 524 | return false; |
| 525 | } | 525 | } |
| 526 | } | 526 | } |
| 527 | else | 527 | else |
| 528 | { | 528 | { |
| 529 | if (!File::Delete(newPath)) | 529 | if (!File::Delete(newPath)) |
| 530 | { | 530 | { |
| 531 | #ifndef _WIN32 | 531 | #ifndef _WIN32 |
| 532 | closedir(dirp); | 532 | closedir(dirp); |
| 533 | #endif | 533 | #endif |
| 534 | 534 | ||
| 535 | return false; | 535 | return false; |
| 536 | } | 536 | } |
| 537 | } | 537 | } |
| 538 | 538 | ||
| 539 | #ifdef _WIN32 | 539 | #ifdef _WIN32 |
| 540 | } while (FindNextFile(hFind, &ffd) != 0); | 540 | } while (FindNextFile(hFind, &ffd) != 0); |
| 541 | FindClose(hFind); | 541 | FindClose(hFind); |
| 542 | #else | 542 | #else |
| 543 | } | 543 | } |
| 544 | closedir(dirp); | 544 | closedir(dirp); |
| 545 | #endif | 545 | #endif |
| 546 | File::DeleteDir(directory); | 546 | File::DeleteDir(directory); |
| 547 | 547 | ||
| 548 | return true; | 548 | return true; |
| 549 | } | 549 | } |
| 550 | 550 | ||
| 551 | // Create directory and copy contents (does not overwrite existing files) | 551 | // Create directory and copy contents (does not overwrite existing files) |
| 552 | void CopyDir(const std::string &source_path, const std::string &dest_path) | 552 | void CopyDir(const std::string &source_path, const std::string &dest_path) |
| 553 | { | 553 | { |
| 554 | #ifndef _WIN32 | 554 | #ifndef _WIN32 |
| 555 | if (source_path == dest_path) return; | 555 | if (source_path == dest_path) return; |
| 556 | if (!File::Exists(source_path)) return; | 556 | if (!File::Exists(source_path)) return; |
| 557 | if (!File::Exists(dest_path)) File::CreateFullPath(dest_path); | 557 | if (!File::Exists(dest_path)) File::CreateFullPath(dest_path); |
| 558 | 558 | ||
| 559 | struct dirent dirent, *result = NULL; | 559 | struct dirent dirent, *result = NULL; |
| 560 | DIR *dirp = opendir(source_path.c_str()); | 560 | DIR *dirp = opendir(source_path.c_str()); |
| 561 | if (!dirp) return; | 561 | if (!dirp) return; |
| 562 | 562 | ||
| 563 | while (!readdir_r(dirp, &dirent, &result) && result) | 563 | while (!readdir_r(dirp, &dirent, &result) && result) |
| 564 | { | 564 | { |
| 565 | const std::string virtualName(result->d_name); | 565 | const std::string virtualName(result->d_name); |
| 566 | // check for "." and ".." | 566 | // check for "." and ".." |
| 567 | if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || | 567 | if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || |
| 568 | ((virtualName[0] == '.') && (virtualName[1] == '.') && | 568 | ((virtualName[0] == '.') && (virtualName[1] == '.') && |
| 569 | (virtualName[2] == '\0'))) | 569 | (virtualName[2] == '\0'))) |
| 570 | continue; | 570 | continue; |
| 571 | 571 | ||
| 572 | std::string source, dest; | 572 | std::string source, dest; |
| 573 | source = source_path + virtualName; | 573 | source = source_path + virtualName; |
| 574 | dest = dest_path + virtualName; | 574 | dest = dest_path + virtualName; |
| 575 | if (IsDirectory(source)) | 575 | if (IsDirectory(source)) |
| 576 | { | 576 | { |
| 577 | source += '/'; | 577 | source += '/'; |
| 578 | dest += '/'; | 578 | dest += '/'; |
| 579 | if (!File::Exists(dest)) File::CreateFullPath(dest); | 579 | if (!File::Exists(dest)) File::CreateFullPath(dest); |
| 580 | CopyDir(source, dest); | 580 | CopyDir(source, dest); |
| 581 | } | 581 | } |
| 582 | else if (!File::Exists(dest)) File::Copy(source, dest); | 582 | else if (!File::Exists(dest)) File::Copy(source, dest); |
| 583 | } | 583 | } |
| 584 | closedir(dirp); | 584 | closedir(dirp); |
| 585 | #endif | 585 | #endif |
| 586 | } | 586 | } |
| 587 | 587 | ||
| 588 | // Returns the current directory | 588 | // Returns the current directory |
| 589 | std::string GetCurrentDir() | 589 | std::string GetCurrentDir() |
| 590 | { | 590 | { |
| 591 | char *dir; | 591 | char *dir; |
| 592 | // Get the current working directory (getcwd uses malloc) | 592 | // Get the current working directory (getcwd uses malloc) |
| 593 | if (!(dir = __getcwd(NULL, 0))) { | 593 | if (!(dir = __getcwd(NULL, 0))) { |
| 594 | 594 | ||
| 595 | ERROR_LOG(COMMON, "GetCurrentDirectory failed: %s", | 595 | ERROR_LOG(COMMON, "GetCurrentDirectory failed: %s", |
| 596 | GetLastErrorMsg()); | 596 | GetLastErrorMsg()); |
| 597 | return NULL; | 597 | return NULL; |
| 598 | } | 598 | } |
| 599 | std::string strDir = dir; | 599 | std::string strDir = dir; |
| 600 | free(dir); | 600 | free(dir); |
| 601 | return strDir; | 601 | return strDir; |
| 602 | } | 602 | } |
| 603 | 603 | ||
| 604 | // Sets the current directory to the given directory | 604 | // Sets the current directory to the given directory |
| 605 | bool SetCurrentDir(const std::string &directory) | 605 | bool SetCurrentDir(const std::string &directory) |
| 606 | { | 606 | { |
| 607 | return __chdir(directory.c_str()) == 0; | 607 | return __chdir(directory.c_str()) == 0; |
| 608 | } | 608 | } |
| 609 | 609 | ||
| 610 | #if defined(__APPLE__) | 610 | #if defined(__APPLE__) |
| 611 | std::string GetBundleDirectory() | 611 | std::string GetBundleDirectory() |
| 612 | { | 612 | { |
| 613 | CFURLRef BundleRef; | 613 | CFURLRef BundleRef; |
| 614 | char AppBundlePath[MAXPATHLEN]; | 614 | char AppBundlePath[MAXPATHLEN]; |
| 615 | // Get the main bundle for the app | 615 | // Get the main bundle for the app |
| 616 | BundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); | 616 | BundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); |
| 617 | CFStringRef BundlePath = CFURLCopyFileSystemPath(BundleRef, kCFURLPOSIXPathStyle); | 617 | CFStringRef BundlePath = CFURLCopyFileSystemPath(BundleRef, kCFURLPOSIXPathStyle); |
| 618 | CFStringGetFileSystemRepresentation(BundlePath, AppBundlePath, sizeof(AppBundlePath)); | 618 | CFStringGetFileSystemRepresentation(BundlePath, AppBundlePath, sizeof(AppBundlePath)); |
| 619 | CFRelease(BundleRef); | 619 | CFRelease(BundleRef); |
| 620 | CFRelease(BundlePath); | 620 | CFRelease(BundlePath); |
| 621 | 621 | ||
| 622 | return AppBundlePath; | 622 | return AppBundlePath; |
| 623 | } | 623 | } |
| 624 | #endif | 624 | #endif |
| 625 | 625 | ||
| 626 | #ifdef _WIN32 | 626 | #ifdef _WIN32 |
| 627 | std::string& GetExeDirectory() | 627 | std::string& GetExeDirectory() |
| 628 | { | 628 | { |
| 629 | static std::string DolphinPath; | 629 | static std::string DolphinPath; |
| 630 | if (DolphinPath.empty()) | 630 | if (DolphinPath.empty()) |
| 631 | { | 631 | { |
| 632 | TCHAR Dolphin_exe_Path[2048]; | 632 | TCHAR Dolphin_exe_Path[2048]; |
| 633 | GetModuleFileName(NULL, Dolphin_exe_Path, 2048); | 633 | GetModuleFileName(NULL, Dolphin_exe_Path, 2048); |
| 634 | DolphinPath = TStrToUTF8(Dolphin_exe_Path); | 634 | DolphinPath = TStrToUTF8(Dolphin_exe_Path); |
| 635 | DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\')); | 635 | DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\')); |
| 636 | } | 636 | } |
| 637 | return DolphinPath; | 637 | return DolphinPath; |
| 638 | } | 638 | } |
| 639 | #endif | 639 | #endif |
| 640 | 640 | ||
| 641 | std::string GetSysDirectory() | 641 | std::string GetSysDirectory() |
| 642 | { | 642 | { |
| 643 | std::string sysDir; | 643 | std::string sysDir; |
| 644 | 644 | ||
| 645 | #if defined (__APPLE__) | 645 | #if defined (__APPLE__) |
| 646 | sysDir = GetBundleDirectory(); | 646 | sysDir = GetBundleDirectory(); |
| 647 | sysDir += DIR_SEP; | 647 | sysDir += DIR_SEP; |
| 648 | sysDir += SYSDATA_DIR; | 648 | sysDir += SYSDATA_DIR; |
| 649 | #else | 649 | #else |
| 650 | sysDir = SYSDATA_DIR; | 650 | sysDir = SYSDATA_DIR; |
| 651 | #endif | 651 | #endif |
| 652 | sysDir += DIR_SEP; | 652 | sysDir += DIR_SEP; |
| 653 | 653 | ||
| 654 | INFO_LOG(COMMON, "GetSysDirectory: Setting to %s:", sysDir.c_str()); | 654 | INFO_LOG(COMMON, "GetSysDirectory: Setting to %s:", sysDir.c_str()); |
| 655 | return sysDir; | 655 | return sysDir; |
| 656 | } | 656 | } |
| 657 | 657 | ||
| 658 | // Returns a string with a Dolphin data dir or file in the user's home | 658 | // Returns a string with a Dolphin data dir or file in the user's home |
| 659 | // directory. To be used in "multi-user" mode (that is, installed). | 659 | // directory. To be used in "multi-user" mode (that is, installed). |
| 660 | const std::string& GetUserPath(const unsigned int DirIDX, const std::string &newPath) | 660 | const std::string& GetUserPath(const unsigned int DirIDX, const std::string &newPath) |
| 661 | { | 661 | { |
| 662 | static std::string paths[NUM_PATH_INDICES]; | 662 | static std::string paths[NUM_PATH_INDICES]; |
| 663 | 663 | ||
| 664 | // Set up all paths and files on the first run | 664 | // Set up all paths and files on the first run |
| 665 | if (paths[D_USER_IDX].empty()) | 665 | if (paths[D_USER_IDX].empty()) |
| 666 | { | 666 | { |
| 667 | #ifdef _WIN32 | 667 | #ifdef _WIN32 |
| 668 | paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; | 668 | paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; |
| 669 | #else | 669 | #else |
| 670 | if (File::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) | 670 | if (File::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) |
| 671 | paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; | 671 | paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; |
| 672 | else | 672 | else |
| 673 | paths[D_USER_IDX] = std::string(getenv("HOME") ? | 673 | paths[D_USER_IDX] = std::string(getenv("HOME") ? |
| 674 | getenv("HOME") : getenv("PWD") ? | 674 | getenv("HOME") : getenv("PWD") ? |
| 675 | getenv("PWD") : "") + DIR_SEP DOLPHIN_DATA_DIR DIR_SEP; | 675 | getenv("PWD") : "") + DIR_SEP DOLPHIN_DATA_DIR DIR_SEP; |
| 676 | #endif | 676 | #endif |
| 677 | 677 | ||
| 678 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; | 678 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; |
| 679 | paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; | 679 | paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; |
| 680 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; | 680 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; |
| 681 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; | 681 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; |
| 682 | paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; | 682 | paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; |
| 683 | paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; | 683 | paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; |
| 684 | paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; | 684 | paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; |
| 685 | paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; | 685 | paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; |
| 686 | paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; | 686 | paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; |
| 687 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; | 687 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; |
| 688 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; | 688 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; |
| 689 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; | 689 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; |
| 690 | paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; | 690 | paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; |
| 691 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; | 691 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; |
| 692 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; | 692 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; |
| 693 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; | 693 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; |
| 694 | } | 694 | } |
| 695 | 695 | ||
| 696 | if (!newPath.empty()) | 696 | if (!newPath.empty()) |
| 697 | { | 697 | { |
| 698 | if (!File::IsDirectory(newPath)) | 698 | if (!File::IsDirectory(newPath)) |
| 699 | { | 699 | { |
| 700 | WARN_LOG(COMMON, "Invalid path specified %s", newPath.c_str()); | 700 | WARN_LOG(COMMON, "Invalid path specified %s", newPath.c_str()); |
| 701 | return paths[DirIDX]; | 701 | return paths[DirIDX]; |
| 702 | } | 702 | } |
| 703 | else | 703 | else |
| 704 | { | 704 | { |
| 705 | paths[DirIDX] = newPath; | 705 | paths[DirIDX] = newPath; |
| 706 | } | 706 | } |
| 707 | 707 | ||
| 708 | switch (DirIDX) | 708 | switch (DirIDX) |
| 709 | { | 709 | { |
| 710 | case D_ROOT_IDX: | 710 | case D_ROOT_IDX: |
| 711 | paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; | 711 | paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; |
| 712 | paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR + DIR_SEP; | 712 | paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR + DIR_SEP; |
| 713 | paths[F_SYSCONF_IDX] = paths[D_SYSCONF_IDX] + SYSCONF; | 713 | paths[F_SYSCONF_IDX] = paths[D_SYSCONF_IDX] + SYSCONF; |
| 714 | break; | 714 | break; |
| 715 | 715 | ||
| 716 | case D_USER_IDX: | 716 | case D_USER_IDX: |
| 717 | paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; | 717 | paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; |
| 718 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; | 718 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; |
| 719 | paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; | 719 | paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; |
| 720 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; | 720 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; |
| 721 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; | 721 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; |
| 722 | paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; | 722 | paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; |
| 723 | paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; | 723 | paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; |
| 724 | paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; | 724 | paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; |
| 725 | paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; | 725 | paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; |
| 726 | paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; | 726 | paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; |
| 727 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; | 727 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; |
| 728 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; | 728 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; |
| 729 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; | 729 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; |
| 730 | paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; | 730 | paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; |
| 731 | paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR DIR_SEP; | 731 | paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR DIR_SEP; |
| 732 | paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; | 732 | paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; |
| 733 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; | 733 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; |
| 734 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; | 734 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; |
| 735 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; | 735 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; |
| 736 | break; | 736 | break; |
| 737 | 737 | ||
| 738 | case D_CONFIG_IDX: | 738 | case D_CONFIG_IDX: |
| 739 | paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; | 739 | paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; |
| 740 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; | 740 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; |
| 741 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; | 741 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; |
| 742 | break; | 742 | break; |
| 743 | 743 | ||
| 744 | case D_DUMP_IDX: | 744 | case D_DUMP_IDX: |
| 745 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; | 745 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; |
| 746 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; | 746 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; |
| 747 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; | 747 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; |
| 748 | break; | 748 | break; |
| 749 | 749 | ||
| 750 | case D_LOGS_IDX: | 750 | case D_LOGS_IDX: |
| 751 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; | 751 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; |
| 752 | } | 752 | } |
| 753 | } | 753 | } |
| 754 | 754 | ||
| 755 | return paths[DirIDX]; | 755 | return paths[DirIDX]; |
| 756 | } | 756 | } |
| 757 | 757 | ||
| 758 | //std::string GetThemeDir(const std::string& theme_name) | 758 | //std::string GetThemeDir(const std::string& theme_name) |
| 759 | //{ | 759 | //{ |
| 760 | // std::string dir = File::GetUserPath(D_THEMES_IDX) + theme_name + "/"; | 760 | // std::string dir = File::GetUserPath(D_THEMES_IDX) + theme_name + "/"; |
| 761 | // | 761 | // |
| 762 | //#if !defined(_WIN32) | 762 | //#if !defined(_WIN32) |
| 763 | // // If theme does not exist in user's dir load from shared directory | 763 | // // If theme does not exist in user's dir load from shared directory |
| 764 | // if (!File::Exists(dir)) | 764 | // if (!File::Exists(dir)) |
| 765 | // dir = SHARED_USER_DIR THEMES_DIR "/" + theme_name + "/"; | 765 | // dir = SHARED_USER_DIR THEMES_DIR "/" + theme_name + "/"; |
| 766 | //#endif | 766 | //#endif |
| 767 | // | 767 | // |
| 768 | // return dir; | 768 | // return dir; |
| 769 | //} | 769 | //} |
| 770 | 770 | ||
| 771 | bool WriteStringToFile(bool text_file, const std::string &str, const char *filename) | 771 | bool WriteStringToFile(bool text_file, const std::string &str, const char *filename) |
| 772 | { | 772 | { |
| 773 | return File::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); | 773 | return File::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); |
| 774 | } | 774 | } |
| 775 | 775 | ||
| 776 | bool ReadFileToString(bool text_file, const char *filename, std::string &str) | 776 | bool ReadFileToString(bool text_file, const char *filename, std::string &str) |
| 777 | { | 777 | { |
| 778 | File::IOFile file(filename, text_file ? "r" : "rb"); | 778 | File::IOFile file(filename, text_file ? "r" : "rb"); |
| 779 | auto const f = file.GetHandle(); | 779 | auto const f = file.GetHandle(); |
| 780 | 780 | ||
| 781 | if (!f) | 781 | if (!f) |
| 782 | return false; | 782 | return false; |
| 783 | 783 | ||
| 784 | str.resize(static_cast<u32>(GetSize(f))); | 784 | str.resize(static_cast<u32>(GetSize(f))); |
| 785 | return file.ReadArray(&str[0], str.size()); | 785 | return file.ReadArray(&str[0], str.size()); |
| 786 | } | 786 | } |
| 787 | 787 | ||
| 788 | IOFile::IOFile() | 788 | IOFile::IOFile() |
| 789 | : m_file(NULL), m_good(true) | 789 | : m_file(NULL), m_good(true) |
| 790 | {} | 790 | {} |
| 791 | 791 | ||
| 792 | IOFile::IOFile(std::FILE* file) | 792 | IOFile::IOFile(std::FILE* file) |
| 793 | : m_file(file), m_good(true) | 793 | : m_file(file), m_good(true) |
| 794 | {} | 794 | {} |
| 795 | 795 | ||
| 796 | IOFile::IOFile(const std::string& filename, const char openmode[]) | 796 | IOFile::IOFile(const std::string& filename, const char openmode[]) |
| 797 | : m_file(NULL), m_good(true) | 797 | : m_file(NULL), m_good(true) |
| 798 | { | 798 | { |
| 799 | Open(filename, openmode); | 799 | Open(filename, openmode); |
| 800 | } | 800 | } |
| 801 | 801 | ||
| 802 | IOFile::~IOFile() | 802 | IOFile::~IOFile() |
| 803 | { | 803 | { |
| 804 | Close(); | 804 | Close(); |
| 805 | } | 805 | } |
| 806 | 806 | ||
| 807 | IOFile::IOFile(IOFile&& other) | 807 | IOFile::IOFile(IOFile&& other) |
| 808 | : m_file(NULL), m_good(true) | 808 | : m_file(NULL), m_good(true) |
| 809 | { | 809 | { |
| 810 | Swap(other); | 810 | Swap(other); |
| 811 | } | 811 | } |
| 812 | 812 | ||
| 813 | IOFile& IOFile::operator=(IOFile&& other) | 813 | IOFile& IOFile::operator=(IOFile&& other) |
| 814 | { | 814 | { |
| 815 | Swap(other); | 815 | Swap(other); |
| 816 | return *this; | 816 | return *this; |
| 817 | } | 817 | } |
| 818 | 818 | ||
| 819 | void IOFile::Swap(IOFile& other) | 819 | void IOFile::Swap(IOFile& other) |
| 820 | { | 820 | { |
| 821 | std::swap(m_file, other.m_file); | 821 | std::swap(m_file, other.m_file); |
| 822 | std::swap(m_good, other.m_good); | 822 | std::swap(m_good, other.m_good); |
| 823 | } | 823 | } |
| 824 | 824 | ||
| 825 | bool IOFile::Open(const std::string& filename, const char openmode[]) | 825 | bool IOFile::Open(const std::string& filename, const char openmode[]) |
| 826 | { | 826 | { |
| 827 | Close(); | 827 | Close(); |
| 828 | #ifdef _WIN32 | 828 | #ifdef _WIN32 |
| 829 | _tfopen_s(&m_file, UTF8ToTStr(filename).c_str(), UTF8ToTStr(openmode).c_str()); | 829 | _tfopen_s(&m_file, UTF8ToTStr(filename).c_str(), UTF8ToTStr(openmode).c_str()); |
| 830 | #else | 830 | #else |
| 831 | m_file = fopen(filename.c_str(), openmode); | 831 | m_file = fopen(filename.c_str(), openmode); |
| 832 | #endif | 832 | #endif |
| 833 | 833 | ||
| 834 | m_good = IsOpen(); | 834 | m_good = IsOpen(); |
| 835 | return m_good; | 835 | return m_good; |
| 836 | } | 836 | } |
| 837 | 837 | ||
| 838 | bool IOFile::Close() | 838 | bool IOFile::Close() |
| 839 | { | 839 | { |
| 840 | if (!IsOpen() || 0 != std::fclose(m_file)) | 840 | if (!IsOpen() || 0 != std::fclose(m_file)) |
| 841 | m_good = false; | 841 | m_good = false; |
| 842 | 842 | ||
| 843 | m_file = NULL; | 843 | m_file = NULL; |
| 844 | return m_good; | 844 | return m_good; |
| 845 | } | 845 | } |
| 846 | 846 | ||
| 847 | std::FILE* IOFile::ReleaseHandle() | 847 | std::FILE* IOFile::ReleaseHandle() |
| 848 | { | 848 | { |
| 849 | std::FILE* const ret = m_file; | 849 | std::FILE* const ret = m_file; |
| 850 | m_file = NULL; | 850 | m_file = NULL; |
| 851 | return ret; | 851 | return ret; |
| 852 | } | 852 | } |
| 853 | 853 | ||
| 854 | void IOFile::SetHandle(std::FILE* file) | 854 | void IOFile::SetHandle(std::FILE* file) |
| 855 | { | 855 | { |
| 856 | Close(); | 856 | Close(); |
| 857 | Clear(); | 857 | Clear(); |
| 858 | m_file = file; | 858 | m_file = file; |
| 859 | } | 859 | } |
| 860 | 860 | ||
| 861 | u64 IOFile::GetSize() | 861 | u64 IOFile::GetSize() |
| 862 | { | 862 | { |
| 863 | if (IsOpen()) | 863 | if (IsOpen()) |
| 864 | return File::GetSize(m_file); | 864 | return File::GetSize(m_file); |
| 865 | else | 865 | else |
| 866 | return 0; | 866 | return 0; |
| 867 | } | 867 | } |
| 868 | 868 | ||
| 869 | bool IOFile::Seek(s64 off, int origin) | 869 | bool IOFile::Seek(s64 off, int origin) |
| 870 | { | 870 | { |
| 871 | if (!IsOpen() || 0 != fseeko(m_file, off, origin)) | 871 | if (!IsOpen() || 0 != fseeko(m_file, off, origin)) |
| 872 | m_good = false; | 872 | m_good = false; |
| 873 | 873 | ||
| 874 | return m_good; | 874 | return m_good; |
| 875 | } | 875 | } |
| 876 | 876 | ||
| 877 | u64 IOFile::Tell() | 877 | u64 IOFile::Tell() |
| 878 | { | 878 | { |
| 879 | if (IsOpen()) | 879 | if (IsOpen()) |
| 880 | return ftello(m_file); | 880 | return ftello(m_file); |
| 881 | else | 881 | else |
| 882 | return -1; | 882 | return -1; |
| 883 | } | 883 | } |
| 884 | 884 | ||
| 885 | bool IOFile::Flush() | 885 | bool IOFile::Flush() |
| 886 | { | 886 | { |
| 887 | if (!IsOpen() || 0 != std::fflush(m_file)) | 887 | if (!IsOpen() || 0 != std::fflush(m_file)) |
| 888 | m_good = false; | 888 | m_good = false; |
| 889 | 889 | ||
| 890 | return m_good; | 890 | return m_good; |
| 891 | } | 891 | } |
| 892 | 892 | ||
| 893 | bool IOFile::Resize(u64 size) | 893 | bool IOFile::Resize(u64 size) |
| 894 | { | 894 | { |
| 895 | if (!IsOpen() || 0 != | 895 | if (!IsOpen() || 0 != |
| 896 | #ifdef _WIN32 | 896 | #ifdef _WIN32 |
| 897 | // ector: _chsize sucks, not 64-bit safe | 897 | // ector: _chsize sucks, not 64-bit safe |
| 898 | // F|RES: changed to _chsize_s. i think it is 64-bit safe | 898 | // F|RES: changed to _chsize_s. i think it is 64-bit safe |
| 899 | _chsize_s(_fileno(m_file), size) | 899 | _chsize_s(_fileno(m_file), size) |
| 900 | #else | 900 | #else |
| 901 | // TODO: handle 64bit and growing | 901 | // TODO: handle 64bit and growing |
| 902 | ftruncate(fileno(m_file), size) | 902 | ftruncate(fileno(m_file), size) |
| 903 | #endif | 903 | #endif |
| 904 | ) | 904 | ) |
| 905 | m_good = false; | 905 | m_good = false; |
| 906 | 906 | ||
| 907 | return m_good; | 907 | return m_good; |
| 908 | } | 908 | } |
| 909 | 909 | ||
| 910 | } // namespace | 910 | } // namespace |
diff --git a/src/common/src/fixed_size_queue.h b/src/common/src/fixed_size_queue.h index 4045dfa33..1f507f4ae 100644 --- a/src/common/src/fixed_size_queue.h +++ b/src/common/src/fixed_size_queue.h | |||
| @@ -16,59 +16,59 @@ | |||
| 16 | template <class T, int N> | 16 | template <class T, int N> |
| 17 | class fixed_size_queue.h | 17 | class fixed_size_queue.h |
| 18 | { | 18 | { |
| 19 | T *storage; | 19 | T *storage; |
| 20 | int head; | 20 | int head; |
| 21 | int tail; | 21 | int tail; |
| 22 | int count; // sacrifice 4 bytes for a simpler implementation. may optimize away in the future. | 22 | int count; // sacrifice 4 bytes for a simpler implementation. may optimize away in the future. |
| 23 | 23 | ||
| 24 | // Make copy constructor private for now. | 24 | // Make copy constructor private for now. |
| 25 | fixed_size_queue.h(fixed_size_queue.h &other) { } | 25 | fixed_size_queue.h(fixed_size_queue.h &other) { } |
| 26 | 26 | ||
| 27 | public: | 27 | public: |
| 28 | fixed_size_queue.h() | 28 | fixed_size_queue.h() |
| 29 | { | 29 | { |
| 30 | storage = new T[N]; | 30 | storage = new T[N]; |
| 31 | clear(); | 31 | clear(); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | ~fixed_size_queue.h() | 34 | ~fixed_size_queue.h() |
| 35 | { | 35 | { |
| 36 | delete [] storage; | 36 | delete [] storage; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void clear() { | 39 | void clear() { |
| 40 | head = 0; | 40 | head = 0; |
| 41 | tail = 0; | 41 | tail = 0; |
| 42 | count = 0; | 42 | count = 0; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | void push(T t) { | 45 | void push(T t) { |
| 46 | storage[tail] = t; | 46 | storage[tail] = t; |
| 47 | tail++; | 47 | tail++; |
| 48 | if (tail == N) | 48 | if (tail == N) |
| 49 | tail = 0; | 49 | tail = 0; |
| 50 | count++; | 50 | count++; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | void pop() { | 53 | void pop() { |
| 54 | head++; | 54 | head++; |
| 55 | if (head == N) | 55 | if (head == N) |
| 56 | head = 0; | 56 | head = 0; |
| 57 | count--; | 57 | count--; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | T pop_front() { | 60 | T pop_front() { |
| 61 | const T &temp = storage[head]; | 61 | const T &temp = storage[head]; |
| 62 | pop(); | 62 | pop(); |
| 63 | return temp; | 63 | return temp; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | T &front() { return storage[head]; } | 66 | T &front() { return storage[head]; } |
| 67 | const T &front() const { return storage[head]; } | 67 | const T &front() const { return storage[head]; } |
| 68 | 68 | ||
| 69 | size_t size() const { | 69 | size_t size() const { |
| 70 | return count; | 70 | return count; |
| 71 | } | 71 | } |
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | #endif // _FIXED_SIZE_QUEUE_H_ | 74 | #endif // _FIXED_SIZE_QUEUE_H_ |
diff --git a/src/common/src/hash.cpp b/src/common/src/hash.cpp index 39c636419..5303f07b5 100644 --- a/src/common/src/hash.cpp +++ b/src/common/src/hash.cpp | |||
| @@ -16,29 +16,29 @@ static u64 (*ptrHashFunction)(const u8 *src, int len, u32 samples) = &GetMurmurH | |||
| 16 | // Implementation from Wikipedia. | 16 | // Implementation from Wikipedia. |
| 17 | u32 HashFletcher(const u8* data_u8, size_t length) | 17 | u32 HashFletcher(const u8* data_u8, size_t length) |
| 18 | { | 18 | { |
| 19 | const u16* data = (const u16*)data_u8; /* Pointer to the data to be summed */ | 19 | const u16* data = (const u16*)data_u8; /* Pointer to the data to be summed */ |
| 20 | size_t len = (length + 1) / 2; /* Length in 16-bit words */ | 20 | size_t len = (length + 1) / 2; /* Length in 16-bit words */ |
| 21 | u32 sum1 = 0xffff, sum2 = 0xffff; | 21 | u32 sum1 = 0xffff, sum2 = 0xffff; |
| 22 | 22 | ||
| 23 | while (len) | 23 | while (len) |
| 24 | { | 24 | { |
| 25 | size_t tlen = len > 360 ? 360 : len; | 25 | size_t tlen = len > 360 ? 360 : len; |
| 26 | len -= tlen; | 26 | len -= tlen; |
| 27 | 27 | ||
| 28 | do { | 28 | do { |
| 29 | sum1 += *data++; | 29 | sum1 += *data++; |
| 30 | sum2 += sum1; | 30 | sum2 += sum1; |
| 31 | } | 31 | } |
| 32 | while (--tlen); | 32 | while (--tlen); |
| 33 | 33 | ||
| 34 | sum1 = (sum1 & 0xffff) + (sum1 >> 16); | 34 | sum1 = (sum1 & 0xffff) + (sum1 >> 16); |
| 35 | sum2 = (sum2 & 0xffff) + (sum2 >> 16); | 35 | sum2 = (sum2 & 0xffff) + (sum2 >> 16); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | // Second reduction step to reduce sums to 16 bits | 38 | // Second reduction step to reduce sums to 16 bits |
| 39 | sum1 = (sum1 & 0xffff) + (sum1 >> 16); | 39 | sum1 = (sum1 & 0xffff) + (sum1 >> 16); |
| 40 | sum2 = (sum2 & 0xffff) + (sum2 >> 16); | 40 | sum2 = (sum2 & 0xffff) + (sum2 >> 16); |
| 41 | return(sum2 << 16 | sum1); | 41 | return(sum2 << 16 | sum1); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | 44 | ||
| @@ -48,54 +48,54 @@ u32 HashFletcher(const u8* data_u8, size_t length) | |||
| 48 | // data: Pointer to the data to be summed; len is in bytes | 48 | // data: Pointer to the data to be summed; len is in bytes |
| 49 | u32 HashAdler32(const u8* data, size_t len) | 49 | u32 HashAdler32(const u8* data, size_t len) |
| 50 | { | 50 | { |
| 51 | u32 a = 1, b = 0; | 51 | u32 a = 1, b = 0; |
| 52 | 52 | ||
| 53 | while (len) | 53 | while (len) |
| 54 | { | 54 | { |
| 55 | size_t tlen = len > 5550 ? 5550 : len; | 55 | size_t tlen = len > 5550 ? 5550 : len; |
| 56 | len -= tlen; | 56 | len -= tlen; |
| 57 | 57 | ||
| 58 | do | 58 | do |
| 59 | { | 59 | { |
| 60 | a += *data++; | 60 | a += *data++; |
| 61 | b += a; | 61 | b += a; |
| 62 | } | 62 | } |
| 63 | while (--tlen); | 63 | while (--tlen); |
| 64 | 64 | ||
| 65 | a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER); | 65 | a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER); |
| 66 | b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); | 66 | b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | // It can be shown that a <= 0x1013a here, so a single subtract will do. | 69 | // It can be shown that a <= 0x1013a here, so a single subtract will do. |
| 70 | if (a >= MOD_ADLER) | 70 | if (a >= MOD_ADLER) |
| 71 | { | 71 | { |
| 72 | a -= MOD_ADLER; | 72 | a -= MOD_ADLER; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | // It can be shown that b can reach 0xfff87 here. | 75 | // It can be shown that b can reach 0xfff87 here. |
| 76 | b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); | 76 | b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); |
| 77 | 77 | ||
| 78 | if (b >= MOD_ADLER) | 78 | if (b >= MOD_ADLER) |
| 79 | { | 79 | { |
| 80 | b -= MOD_ADLER; | 80 | b -= MOD_ADLER; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | return((b << 16) | a); | 83 | return((b << 16) | a); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | // Stupid hash - but can't go back now :) | 86 | // Stupid hash - but can't go back now :) |
| 87 | // Don't use for new things. At least it's reasonably fast. | 87 | // Don't use for new things. At least it's reasonably fast. |
| 88 | u32 HashEctor(const u8* ptr, int length) | 88 | u32 HashEctor(const u8* ptr, int length) |
| 89 | { | 89 | { |
| 90 | u32 crc = 0; | 90 | u32 crc = 0; |
| 91 | 91 | ||
| 92 | for (int i = 0; i < length; i++) | 92 | for (int i = 0; i < length; i++) |
| 93 | { | 93 | { |
| 94 | crc ^= ptr[i]; | 94 | crc ^= ptr[i]; |
| 95 | crc = (crc << 3) | (crc >> 29); | 95 | crc = (crc << 3) | (crc >> 29); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | return(crc); | 98 | return(crc); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | 101 | ||
| @@ -107,7 +107,7 @@ u32 HashEctor(const u8* ptr, int length) | |||
| 107 | 107 | ||
| 108 | inline u64 getblock(const u64 * p, int i) | 108 | inline u64 getblock(const u64 * p, int i) |
| 109 | { | 109 | { |
| 110 | return p[i]; | 110 | return p[i]; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | //---------- | 113 | //---------- |
| @@ -115,25 +115,25 @@ inline u64 getblock(const u64 * p, int i) | |||
| 115 | 115 | ||
| 116 | inline void bmix64(u64 & h1, u64 & h2, u64 & k1, u64 & k2, u64 & c1, u64 & c2) | 116 | inline void bmix64(u64 & h1, u64 & h2, u64 & k1, u64 & k2, u64 & c1, u64 & c2) |
| 117 | { | 117 | { |
| 118 | k1 *= c1; | 118 | k1 *= c1; |
| 119 | k1 = _rotl64(k1,23); | 119 | k1 = _rotl64(k1,23); |
| 120 | k1 *= c2; | 120 | k1 *= c2; |
| 121 | h1 ^= k1; | 121 | h1 ^= k1; |
| 122 | h1 += h2; | 122 | h1 += h2; |
| 123 | 123 | ||
| 124 | h2 = _rotl64(h2,41); | 124 | h2 = _rotl64(h2,41); |
| 125 | 125 | ||
| 126 | k2 *= c2; | 126 | k2 *= c2; |
| 127 | k2 = _rotl64(k2,23); | 127 | k2 = _rotl64(k2,23); |
| 128 | k2 *= c1; | 128 | k2 *= c1; |
| 129 | h2 ^= k2; | 129 | h2 ^= k2; |
| 130 | h2 += h1; | 130 | h2 += h1; |
| 131 | 131 | ||
| 132 | h1 = h1*3+0x52dce729; | 132 | h1 = h1*3+0x52dce729; |
| 133 | h2 = h2*3+0x38495ab5; | 133 | h2 = h2*3+0x38495ab5; |
| 134 | 134 | ||
| 135 | c1 = c1*5+0x7b7d159c; | 135 | c1 = c1*5+0x7b7d159c; |
| 136 | c2 = c2*5+0x6bce6396; | 136 | c2 = c2*5+0x6bce6396; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | //---------- | 139 | //---------- |
| @@ -141,87 +141,87 @@ inline void bmix64(u64 & h1, u64 & h2, u64 & k1, u64 & k2, u64 & c1, u64 & c2) | |||
| 141 | 141 | ||
| 142 | inline u64 fmix64(u64 k) | 142 | inline u64 fmix64(u64 k) |
| 143 | { | 143 | { |
| 144 | k ^= k >> 33; | 144 | k ^= k >> 33; |
| 145 | k *= 0xff51afd7ed558ccd; | 145 | k *= 0xff51afd7ed558ccd; |
| 146 | k ^= k >> 33; | 146 | k ^= k >> 33; |
| 147 | k *= 0xc4ceb9fe1a85ec53; | 147 | k *= 0xc4ceb9fe1a85ec53; |
| 148 | k ^= k >> 33; | 148 | k ^= k >> 33; |
| 149 | 149 | ||
| 150 | return k; | 150 | return k; |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | u64 GetMurmurHash3(const u8 *src, int len, u32 samples) | 153 | u64 GetMurmurHash3(const u8 *src, int len, u32 samples) |
| 154 | { | 154 | { |
| 155 | const u8 * data = (const u8*)src; | 155 | const u8 * data = (const u8*)src; |
| 156 | const int nblocks = len / 16; | 156 | const int nblocks = len / 16; |
| 157 | u32 Step = (len / 8); | 157 | u32 Step = (len / 8); |
| 158 | if(samples == 0) samples = max(Step, 1u); | 158 | if(samples == 0) samples = max(Step, 1u); |
| 159 | Step = Step / samples; | 159 | Step = Step / samples; |
| 160 | if(Step < 1) Step = 1; | 160 | if(Step < 1) Step = 1; |
| 161 | 161 | ||
| 162 | u64 h1 = 0x9368e53c2f6af274; | 162 | u64 h1 = 0x9368e53c2f6af274; |
| 163 | u64 h2 = 0x586dcd208f7cd3fd; | 163 | u64 h2 = 0x586dcd208f7cd3fd; |
| 164 | 164 | ||
| 165 | u64 c1 = 0x87c37b91114253d5; | 165 | u64 c1 = 0x87c37b91114253d5; |
| 166 | u64 c2 = 0x4cf5ad432745937f; | 166 | u64 c2 = 0x4cf5ad432745937f; |
| 167 | 167 | ||
| 168 | 168 | ||
| 169 | //---------- | 169 | //---------- |
| 170 | // body | 170 | // body |
| 171 | 171 | ||
| 172 | const u64 * blocks = (const u64 *)(data); | 172 | const u64 * blocks = (const u64 *)(data); |
| 173 | 173 | ||
| 174 | for(int i = 0; i < nblocks; i+=Step) | 174 | for(int i = 0; i < nblocks; i+=Step) |
| 175 | { | 175 | { |
| 176 | u64 k1 = getblock(blocks,i*2+0); | 176 | u64 k1 = getblock(blocks,i*2+0); |
| 177 | u64 k2 = getblock(blocks,i*2+1); | 177 | u64 k2 = getblock(blocks,i*2+1); |
| 178 | 178 | ||
| 179 | bmix64(h1,h2,k1,k2,c1,c2); | 179 | bmix64(h1,h2,k1,k2,c1,c2); |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | //---------- | 182 | //---------- |
| 183 | // tail | 183 | // tail |
| 184 | 184 | ||
| 185 | const u8 * tail = (const u8*)(data + nblocks*16); | 185 | const u8 * tail = (const u8*)(data + nblocks*16); |
| 186 | 186 | ||
| 187 | u64 k1 = 0; | 187 | u64 k1 = 0; |
| 188 | u64 k2 = 0; | 188 | u64 k2 = 0; |
| 189 | 189 | ||
| 190 | switch(len & 15) | 190 | switch(len & 15) |
| 191 | { | 191 | { |
| 192 | case 15: k2 ^= u64(tail[14]) << 48; | 192 | case 15: k2 ^= u64(tail[14]) << 48; |
| 193 | case 14: k2 ^= u64(tail[13]) << 40; | 193 | case 14: k2 ^= u64(tail[13]) << 40; |
| 194 | case 13: k2 ^= u64(tail[12]) << 32; | 194 | case 13: k2 ^= u64(tail[12]) << 32; |
| 195 | case 12: k2 ^= u64(tail[11]) << 24; | 195 | case 12: k2 ^= u64(tail[11]) << 24; |
| 196 | case 11: k2 ^= u64(tail[10]) << 16; | 196 | case 11: k2 ^= u64(tail[10]) << 16; |
| 197 | case 10: k2 ^= u64(tail[ 9]) << 8; | 197 | case 10: k2 ^= u64(tail[ 9]) << 8; |
| 198 | case 9: k2 ^= u64(tail[ 8]) << 0; | 198 | case 9: k2 ^= u64(tail[ 8]) << 0; |
| 199 | 199 | ||
| 200 | case 8: k1 ^= u64(tail[ 7]) << 56; | 200 | case 8: k1 ^= u64(tail[ 7]) << 56; |
| 201 | case 7: k1 ^= u64(tail[ 6]) << 48; | 201 | case 7: k1 ^= u64(tail[ 6]) << 48; |
| 202 | case 6: k1 ^= u64(tail[ 5]) << 40; | 202 | case 6: k1 ^= u64(tail[ 5]) << 40; |
| 203 | case 5: k1 ^= u64(tail[ 4]) << 32; | 203 | case 5: k1 ^= u64(tail[ 4]) << 32; |
| 204 | case 4: k1 ^= u64(tail[ 3]) << 24; | 204 | case 4: k1 ^= u64(tail[ 3]) << 24; |
| 205 | case 3: k1 ^= u64(tail[ 2]) << 16; | 205 | case 3: k1 ^= u64(tail[ 2]) << 16; |
| 206 | case 2: k1 ^= u64(tail[ 1]) << 8; | 206 | case 2: k1 ^= u64(tail[ 1]) << 8; |
| 207 | case 1: k1 ^= u64(tail[ 0]) << 0; | 207 | case 1: k1 ^= u64(tail[ 0]) << 0; |
| 208 | bmix64(h1,h2,k1,k2,c1,c2); | 208 | bmix64(h1,h2,k1,k2,c1,c2); |
| 209 | }; | 209 | }; |
| 210 | 210 | ||
| 211 | //---------- | 211 | //---------- |
| 212 | // finalization | 212 | // finalization |
| 213 | 213 | ||
| 214 | h2 ^= len; | 214 | h2 ^= len; |
| 215 | 215 | ||
| 216 | h1 += h2; | 216 | h1 += h2; |
| 217 | h2 += h1; | 217 | h2 += h1; |
| 218 | 218 | ||
| 219 | h1 = fmix64(h1); | 219 | h1 = fmix64(h1); |
| 220 | h2 = fmix64(h2); | 220 | h2 = fmix64(h2); |
| 221 | 221 | ||
| 222 | h1 += h2; | 222 | h1 += h2; |
| 223 | 223 | ||
| 224 | return h1; | 224 | return h1; |
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | 227 | ||
| @@ -229,23 +229,23 @@ u64 GetMurmurHash3(const u8 *src, int len, u32 samples) | |||
| 229 | u64 GetCRC32(const u8 *src, int len, u32 samples) | 229 | u64 GetCRC32(const u8 *src, int len, u32 samples) |
| 230 | { | 230 | { |
| 231 | #if _M_SSE >= 0x402 | 231 | #if _M_SSE >= 0x402 |
| 232 | u64 h = len; | 232 | u64 h = len; |
| 233 | u32 Step = (len / 8); | 233 | u32 Step = (len / 8); |
| 234 | const u64 *data = (const u64 *)src; | 234 | const u64 *data = (const u64 *)src; |
| 235 | const u64 *end = data + Step; | 235 | const u64 *end = data + Step; |
| 236 | if(samples == 0) samples = max(Step, 1u); | 236 | if(samples == 0) samples = max(Step, 1u); |
| 237 | Step = Step / samples; | 237 | Step = Step / samples; |
| 238 | if(Step < 1) Step = 1; | 238 | if(Step < 1) Step = 1; |
| 239 | while(data < end) | 239 | while(data < end) |
| 240 | { | 240 | { |
| 241 | h = _mm_crc32_u64(h, data[0]); | 241 | h = _mm_crc32_u64(h, data[0]); |
| 242 | data += Step; | 242 | data += Step; |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | const u8 *data2 = (const u8*)end; | 245 | const u8 *data2 = (const u8*)end; |
| 246 | return _mm_crc32_u64(h, u64(data2[0])); | 246 | return _mm_crc32_u64(h, u64(data2[0])); |
| 247 | #else | 247 | #else |
| 248 | return 0; | 248 | return 0; |
| 249 | #endif | 249 | #endif |
| 250 | } | 250 | } |
| 251 | 251 | ||
| @@ -259,68 +259,68 @@ u64 GetCRC32(const u8 *src, int len, u32 samples) | |||
| 259 | */ | 259 | */ |
| 260 | u64 GetHashHiresTexture(const u8 *src, int len, u32 samples) | 260 | u64 GetHashHiresTexture(const u8 *src, int len, u32 samples) |
| 261 | { | 261 | { |
| 262 | const u64 m = 0xc6a4a7935bd1e995; | 262 | const u64 m = 0xc6a4a7935bd1e995; |
| 263 | u64 h = len * m; | 263 | u64 h = len * m; |
| 264 | const int r = 47; | 264 | const int r = 47; |
| 265 | u32 Step = (len / 8); | 265 | u32 Step = (len / 8); |
| 266 | const u64 *data = (const u64 *)src; | 266 | const u64 *data = (const u64 *)src; |
| 267 | const u64 *end = data + Step; | 267 | const u64 *end = data + Step; |
| 268 | if(samples == 0) samples = max(Step, 1u); | 268 | if(samples == 0) samples = max(Step, 1u); |
| 269 | Step = Step / samples; | 269 | Step = Step / samples; |
| 270 | if(Step < 1) Step = 1; | 270 | if(Step < 1) Step = 1; |
| 271 | while(data < end) | 271 | while(data < end) |
| 272 | { | 272 | { |
| 273 | u64 k = data[0]; | 273 | u64 k = data[0]; |
| 274 | data+=Step; | 274 | data+=Step; |
| 275 | k *= m; | 275 | k *= m; |
| 276 | k ^= k >> r; | 276 | k ^= k >> r; |
| 277 | k *= m; | 277 | k *= m; |
| 278 | h ^= k; | 278 | h ^= k; |
| 279 | h *= m; | 279 | h *= m; |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | const u8 * data2 = (const u8*)end; | 282 | const u8 * data2 = (const u8*)end; |
| 283 | 283 | ||
| 284 | switch(len & 7) | 284 | switch(len & 7) |
| 285 | { | 285 | { |
| 286 | case 7: h ^= u64(data2[6]) << 48; | 286 | case 7: h ^= u64(data2[6]) << 48; |
| 287 | case 6: h ^= u64(data2[5]) << 40; | 287 | case 6: h ^= u64(data2[5]) << 40; |
| 288 | case 5: h ^= u64(data2[4]) << 32; | 288 | case 5: h ^= u64(data2[4]) << 32; |
| 289 | case 4: h ^= u64(data2[3]) << 24; | 289 | case 4: h ^= u64(data2[3]) << 24; |
| 290 | case 3: h ^= u64(data2[2]) << 16; | 290 | case 3: h ^= u64(data2[2]) << 16; |
| 291 | case 2: h ^= u64(data2[1]) << 8; | 291 | case 2: h ^= u64(data2[1]) << 8; |
| 292 | case 1: h ^= u64(data2[0]); | 292 | case 1: h ^= u64(data2[0]); |
| 293 | h *= m; | 293 | h *= m; |
| 294 | }; | 294 | }; |
| 295 | 295 | ||
| 296 | h ^= h >> r; | 296 | h ^= h >> r; |
| 297 | h *= m; | 297 | h *= m; |
| 298 | h ^= h >> r; | 298 | h ^= h >> r; |
| 299 | 299 | ||
| 300 | return h; | 300 | return h; |
| 301 | } | 301 | } |
| 302 | #else | 302 | #else |
| 303 | // CRC32 hash using the SSE4.2 instruction | 303 | // CRC32 hash using the SSE4.2 instruction |
| 304 | u64 GetCRC32(const u8 *src, int len, u32 samples) | 304 | u64 GetCRC32(const u8 *src, int len, u32 samples) |
| 305 | { | 305 | { |
| 306 | #if _M_SSE >= 0x402 | 306 | #if _M_SSE >= 0x402 |
| 307 | u32 h = len; | 307 | u32 h = len; |
| 308 | u32 Step = (len/4); | 308 | u32 Step = (len/4); |
| 309 | const u32 *data = (const u32 *)src; | 309 | const u32 *data = (const u32 *)src; |
| 310 | const u32 *end = data + Step; | 310 | const u32 *end = data + Step; |
| 311 | if(samples == 0) samples = max(Step, 1u); | 311 | if(samples == 0) samples = max(Step, 1u); |
| 312 | Step = Step / samples; | 312 | Step = Step / samples; |
| 313 | if(Step < 1) Step = 1; | 313 | if(Step < 1) Step = 1; |
| 314 | while(data < end) | 314 | while(data < end) |
| 315 | { | 315 | { |
| 316 | h = _mm_crc32_u32(h, data[0]); | 316 | h = _mm_crc32_u32(h, data[0]); |
| 317 | data += Step; | 317 | data += Step; |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | const u8 *data2 = (const u8*)end; | 320 | const u8 *data2 = (const u8*)end; |
| 321 | return (u64)_mm_crc32_u32(h, u32(data2[0])); | 321 | return (u64)_mm_crc32_u32(h, u32(data2[0])); |
| 322 | #else | 322 | #else |
| 323 | return 0; | 323 | return 0; |
| 324 | #endif | 324 | #endif |
| 325 | } | 325 | } |
| 326 | 326 | ||
| @@ -330,7 +330,7 @@ u64 GetCRC32(const u8 *src, int len, u32 samples) | |||
| 330 | 330 | ||
| 331 | inline u32 getblock(const u32 * p, int i) | 331 | inline u32 getblock(const u32 * p, int i) |
| 332 | { | 332 | { |
| 333 | return p[i]; | 333 | return p[i]; |
| 334 | } | 334 | } |
| 335 | 335 | ||
| 336 | //---------- | 336 | //---------- |
| @@ -340,107 +340,107 @@ inline u32 getblock(const u32 * p, int i) | |||
| 340 | 340 | ||
| 341 | inline u32 fmix32(u32 h) | 341 | inline u32 fmix32(u32 h) |
| 342 | { | 342 | { |
| 343 | h ^= h >> 16; | 343 | h ^= h >> 16; |
| 344 | h *= 0x85ebca6b; | 344 | h *= 0x85ebca6b; |
| 345 | h ^= h >> 13; | 345 | h ^= h >> 13; |
| 346 | h *= 0xc2b2ae35; | 346 | h *= 0xc2b2ae35; |
| 347 | h ^= h >> 16; | 347 | h ^= h >> 16; |
| 348 | 348 | ||
| 349 | return h; | 349 | return h; |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | inline void bmix32(u32 & h1, u32 & h2, u32 & k1, u32 & k2, u32 & c1, u32 & c2) | 352 | inline void bmix32(u32 & h1, u32 & h2, u32 & k1, u32 & k2, u32 & c1, u32 & c2) |
| 353 | { | 353 | { |
| 354 | k1 *= c1; | 354 | k1 *= c1; |
| 355 | k1 = _rotl(k1,11); | 355 | k1 = _rotl(k1,11); |
| 356 | k1 *= c2; | 356 | k1 *= c2; |
| 357 | h1 ^= k1; | 357 | h1 ^= k1; |
| 358 | h1 += h2; | 358 | h1 += h2; |
| 359 | 359 | ||
| 360 | h2 = _rotl(h2,17); | 360 | h2 = _rotl(h2,17); |
| 361 | 361 | ||
| 362 | k2 *= c2; | 362 | k2 *= c2; |
| 363 | k2 = _rotl(k2,11); | 363 | k2 = _rotl(k2,11); |
| 364 | k2 *= c1; | 364 | k2 *= c1; |
| 365 | h2 ^= k2; | 365 | h2 ^= k2; |
| 366 | h2 += h1; | 366 | h2 += h1; |
| 367 | 367 | ||
| 368 | h1 = h1*3+0x52dce729; | 368 | h1 = h1*3+0x52dce729; |
| 369 | h2 = h2*3+0x38495ab5; | 369 | h2 = h2*3+0x38495ab5; |
| 370 | 370 | ||
| 371 | c1 = c1*5+0x7b7d159c; | 371 | c1 = c1*5+0x7b7d159c; |
| 372 | c2 = c2*5+0x6bce6396; | 372 | c2 = c2*5+0x6bce6396; |
| 373 | } | 373 | } |
| 374 | 374 | ||
| 375 | //---------- | 375 | //---------- |
| 376 | 376 | ||
| 377 | u64 GetMurmurHash3(const u8* src, int len, u32 samples) | 377 | u64 GetMurmurHash3(const u8* src, int len, u32 samples) |
| 378 | { | 378 | { |
| 379 | const u8 * data = (const u8*)src; | 379 | const u8 * data = (const u8*)src; |
| 380 | u32 out[2]; | 380 | u32 out[2]; |
| 381 | const int nblocks = len / 8; | 381 | const int nblocks = len / 8; |
| 382 | u32 Step = (len / 4); | 382 | u32 Step = (len / 4); |
| 383 | if(samples == 0) samples = max(Step, 1u); | 383 | if(samples == 0) samples = max(Step, 1u); |
| 384 | Step = Step / samples; | 384 | Step = Step / samples; |
| 385 | if(Step < 1) Step = 1; | 385 | if(Step < 1) Step = 1; |
| 386 | 386 | ||
| 387 | u32 h1 = 0x8de1c3ac; | 387 | u32 h1 = 0x8de1c3ac; |
| 388 | u32 h2 = 0xbab98226; | 388 | u32 h2 = 0xbab98226; |
| 389 | 389 | ||
| 390 | u32 c1 = 0x95543787; | 390 | u32 c1 = 0x95543787; |
| 391 | u32 c2 = 0x2ad7eb25; | 391 | u32 c2 = 0x2ad7eb25; |
| 392 | 392 | ||
| 393 | //---------- | 393 | //---------- |
| 394 | // body | 394 | // body |
| 395 | 395 | ||
| 396 | const u32 * blocks = (const u32 *)(data + nblocks*8); | 396 | const u32 * blocks = (const u32 *)(data + nblocks*8); |
| 397 | 397 | ||
| 398 | for(int i = -nblocks; i < 0; i+=Step) | 398 | for(int i = -nblocks; i < 0; i+=Step) |
| 399 | { | 399 | { |
| 400 | u32 k1 = getblock(blocks,i*2+0); | 400 | u32 k1 = getblock(blocks,i*2+0); |
| 401 | u32 k2 = getblock(blocks,i*2+1); | 401 | u32 k2 = getblock(blocks,i*2+1); |
| 402 | 402 | ||
| 403 | bmix32(h1,h2,k1,k2,c1,c2); | 403 | bmix32(h1,h2,k1,k2,c1,c2); |
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | //---------- | 406 | //---------- |
| 407 | // tail | 407 | // tail |
| 408 | 408 | ||
| 409 | const u8 * tail = (const u8*)(data + nblocks*8); | 409 | const u8 * tail = (const u8*)(data + nblocks*8); |
| 410 | 410 | ||
| 411 | u32 k1 = 0; | 411 | u32 k1 = 0; |
| 412 | u32 k2 = 0; | 412 | u32 k2 = 0; |
| 413 | 413 | ||
| 414 | switch(len & 7) | 414 | switch(len & 7) |
| 415 | { | 415 | { |
| 416 | case 7: k2 ^= tail[6] << 16; | 416 | case 7: k2 ^= tail[6] << 16; |
| 417 | case 6: k2 ^= tail[5] << 8; | 417 | case 6: k2 ^= tail[5] << 8; |
| 418 | case 5: k2 ^= tail[4] << 0; | 418 | case 5: k2 ^= tail[4] << 0; |
| 419 | case 4: k1 ^= tail[3] << 24; | 419 | case 4: k1 ^= tail[3] << 24; |
| 420 | case 3: k1 ^= tail[2] << 16; | 420 | case 3: k1 ^= tail[2] << 16; |
| 421 | case 2: k1 ^= tail[1] << 8; | 421 | case 2: k1 ^= tail[1] << 8; |
| 422 | case 1: k1 ^= tail[0] << 0; | 422 | case 1: k1 ^= tail[0] << 0; |
| 423 | bmix32(h1,h2,k1,k2,c1,c2); | 423 | bmix32(h1,h2,k1,k2,c1,c2); |
| 424 | }; | 424 | }; |
| 425 | 425 | ||
| 426 | //---------- | 426 | //---------- |
| 427 | // finalization | 427 | // finalization |
| 428 | 428 | ||
| 429 | h2 ^= len; | 429 | h2 ^= len; |
| 430 | 430 | ||
| 431 | h1 += h2; | 431 | h1 += h2; |
| 432 | h2 += h1; | 432 | h2 += h1; |
| 433 | 433 | ||
| 434 | h1 = fmix32(h1); | 434 | h1 = fmix32(h1); |
| 435 | h2 = fmix32(h2); | 435 | h2 = fmix32(h2); |
| 436 | 436 | ||
| 437 | h1 += h2; | 437 | h1 += h2; |
| 438 | h2 += h1; | 438 | h2 += h1; |
| 439 | 439 | ||
| 440 | out[0] = h1; | 440 | out[0] = h1; |
| 441 | out[1] = h2; | 441 | out[1] = h2; |
| 442 | 442 | ||
| 443 | return *((u64 *)&out); | 443 | return *((u64 *)&out); |
| 444 | } | 444 | } |
| 445 | 445 | ||
| 446 | /* | 446 | /* |
| @@ -450,70 +450,70 @@ u64 GetMurmurHash3(const u8* src, int len, u32 samples) | |||
| 450 | */ | 450 | */ |
| 451 | u64 GetHashHiresTexture(const u8 *src, int len, u32 samples) | 451 | u64 GetHashHiresTexture(const u8 *src, int len, u32 samples) |
| 452 | { | 452 | { |
| 453 | const u64 m = 0xc6a4a7935bd1e995ULL; | 453 | const u64 m = 0xc6a4a7935bd1e995ULL; |
| 454 | u64 h = len * m; | 454 | u64 h = len * m; |
| 455 | const int r = 47; | 455 | const int r = 47; |
| 456 | u32 Step = (len / 8); | 456 | u32 Step = (len / 8); |
| 457 | const u64 *data = (const u64 *)src; | 457 | const u64 *data = (const u64 *)src; |
| 458 | const u64 *end = data + Step; | 458 | const u64 *end = data + Step; |
| 459 | if(samples == 0) samples = max(Step, 1u); | 459 | if(samples == 0) samples = max(Step, 1u); |
| 460 | Step = Step / samples; | 460 | Step = Step / samples; |
| 461 | if(Step < 1) Step = 1; | 461 | if(Step < 1) Step = 1; |
| 462 | while(data < end) | 462 | while(data < end) |
| 463 | { | 463 | { |
| 464 | u64 k = data[0]; | 464 | u64 k = data[0]; |
| 465 | data+=Step; | 465 | data+=Step; |
| 466 | k *= m; | 466 | k *= m; |
| 467 | k ^= k >> r; | 467 | k ^= k >> r; |
| 468 | k *= m; | 468 | k *= m; |
| 469 | h ^= k; | 469 | h ^= k; |
| 470 | h *= m; | 470 | h *= m; |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | const u8 * data2 = (const u8*)end; | 473 | const u8 * data2 = (const u8*)end; |
| 474 | 474 | ||
| 475 | switch(len & 7) | 475 | switch(len & 7) |
| 476 | { | 476 | { |
| 477 | case 7: h ^= u64(data2[6]) << 48; | 477 | case 7: h ^= u64(data2[6]) << 48; |
| 478 | case 6: h ^= u64(data2[5]) << 40; | 478 | case 6: h ^= u64(data2[5]) << 40; |
| 479 | case 5: h ^= u64(data2[4]) << 32; | 479 | case 5: h ^= u64(data2[4]) << 32; |
| 480 | case 4: h ^= u64(data2[3]) << 24; | 480 | case 4: h ^= u64(data2[3]) << 24; |
| 481 | case 3: h ^= u64(data2[2]) << 16; | 481 | case 3: h ^= u64(data2[2]) << 16; |
| 482 | case 2: h ^= u64(data2[1]) << 8; | 482 | case 2: h ^= u64(data2[1]) << 8; |
| 483 | case 1: h ^= u64(data2[0]); | 483 | case 1: h ^= u64(data2[0]); |
| 484 | h *= m; | 484 | h *= m; |
| 485 | }; | 485 | }; |
| 486 | 486 | ||
| 487 | h ^= h >> r; | 487 | h ^= h >> r; |
| 488 | h *= m; | 488 | h *= m; |
| 489 | h ^= h >> r; | 489 | h ^= h >> r; |
| 490 | 490 | ||
| 491 | return h; | 491 | return h; |
| 492 | } | 492 | } |
| 493 | #endif | 493 | #endif |
| 494 | 494 | ||
| 495 | u64 GetHash64(const u8 *src, int len, u32 samples) | 495 | u64 GetHash64(const u8 *src, int len, u32 samples) |
| 496 | { | 496 | { |
| 497 | return ptrHashFunction(src, len, samples); | 497 | return ptrHashFunction(src, len, samples); |
| 498 | } | 498 | } |
| 499 | 499 | ||
| 500 | // sets the hash function used for the texture cache | 500 | // sets the hash function used for the texture cache |
| 501 | void SetHash64Function(bool useHiresTextures) | 501 | void SetHash64Function(bool useHiresTextures) |
| 502 | { | 502 | { |
| 503 | if (useHiresTextures) | 503 | if (useHiresTextures) |
| 504 | { | 504 | { |
| 505 | ptrHashFunction = &GetHashHiresTexture; | 505 | ptrHashFunction = &GetHashHiresTexture; |
| 506 | } | 506 | } |
| 507 | #if _M_SSE >= 0x402 | 507 | #if _M_SSE >= 0x402 |
| 508 | else if (cpu_info.bSSE4_2 && !useHiresTextures) // sse crc32 version | 508 | else if (cpu_info.bSSE4_2 && !useHiresTextures) // sse crc32 version |
| 509 | { | 509 | { |
| 510 | ptrHashFunction = &GetCRC32; | 510 | ptrHashFunction = &GetCRC32; |
| 511 | } | 511 | } |
| 512 | #endif | 512 | #endif |
| 513 | else | 513 | else |
| 514 | { | 514 | { |
| 515 | ptrHashFunction = &GetMurmurHash3; | 515 | ptrHashFunction = &GetMurmurHash3; |
| 516 | } | 516 | } |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | 519 | ||
diff --git a/src/common/src/linear_disk_cache.h b/src/common/src/linear_disk_cache.h index d33ee7820..da5d6b9b4 100644 --- a/src/common/src/linear_disk_cache.h +++ b/src/common/src/linear_disk_cache.h | |||
| @@ -30,7 +30,7 @@ template <typename K, typename V> | |||
| 30 | class LinearDiskCacheReader | 30 | class LinearDiskCacheReader |
| 31 | { | 31 | { |
| 32 | public: | 32 | public: |
| 33 | virtual void Read(const K &key, const V *value, u32 value_size) = 0; | 33 | virtual void Read(const K &key, const V *value, u32 value_size) = 0; |
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | // Dead simple unsorted key-value store with append functionality. | 36 | // Dead simple unsorted key-value store with append functionality. |
| @@ -49,143 +49,143 @@ template <typename K, typename V> | |||
| 49 | class LinearDiskCache | 49 | class LinearDiskCache |
| 50 | { | 50 | { |
| 51 | public: | 51 | public: |
| 52 | // return number of read entries | 52 | // return number of read entries |
| 53 | u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader) | 53 | u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader) |
| 54 | { | 54 | { |
| 55 | using std::ios_base; | 55 | using std::ios_base; |
| 56 | 56 | ||
| 57 | // close any currently opened file | 57 | // close any currently opened file |
| 58 | Close(); | 58 | Close(); |
| 59 | m_num_entries = 0; | 59 | m_num_entries = 0; |
| 60 | 60 | ||
| 61 | // try opening for reading/writing | 61 | // try opening for reading/writing |
| 62 | OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary); | 62 | OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary); |
| 63 | 63 | ||
| 64 | m_file.seekg(0, std::ios::end); | 64 | m_file.seekg(0, std::ios::end); |
| 65 | std::fstream::pos_type end_pos = m_file.tellg(); | 65 | std::fstream::pos_type end_pos = m_file.tellg(); |
| 66 | m_file.seekg(0, std::ios::beg); | 66 | m_file.seekg(0, std::ios::beg); |
| 67 | std::fstream::pos_type start_pos = m_file.tellg(); | 67 | std::fstream::pos_type start_pos = m_file.tellg(); |
| 68 | std::streamoff file_size = end_pos - start_pos; | 68 | std::streamoff file_size = end_pos - start_pos; |
| 69 | 69 | ||
| 70 | if (m_file.is_open() && ValidateHeader()) | 70 | if (m_file.is_open() && ValidateHeader()) |
| 71 | { | 71 | { |
| 72 | // good header, read some key/value pairs | 72 | // good header, read some key/value pairs |
| 73 | K key; | 73 | K key; |
| 74 | 74 | ||
| 75 | V *value = NULL; | 75 | V *value = NULL; |
| 76 | u32 value_size; | 76 | u32 value_size; |
| 77 | u32 entry_number; | 77 | u32 entry_number; |
| 78 | 78 | ||
| 79 | std::fstream::pos_type last_pos = m_file.tellg(); | 79 | std::fstream::pos_type last_pos = m_file.tellg(); |
| 80 | 80 | ||
| 81 | while (Read(&value_size)) | 81 | while (Read(&value_size)) |
| 82 | { | 82 | { |
| 83 | std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size; | 83 | std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size; |
| 84 | if (next_extent > file_size) | 84 | if (next_extent > file_size) |
| 85 | break; | 85 | break; |
| 86 | 86 | ||
| 87 | delete[] value; | 87 | delete[] value; |
| 88 | value = new V[value_size]; | 88 | value = new V[value_size]; |
| 89 | 89 | ||
| 90 | // read key/value and pass to reader | 90 | // read key/value and pass to reader |
| 91 | if (Read(&key) && | 91 | if (Read(&key) && |
| 92 | Read(value, value_size) && | 92 | Read(value, value_size) && |
| 93 | Read(&entry_number) && | 93 | Read(&entry_number) && |
| 94 | entry_number == m_num_entries+1) | 94 | entry_number == m_num_entries+1) |
| 95 | { | 95 | { |
| 96 | reader.Read(key, value, value_size); | 96 | reader.Read(key, value, value_size); |
| 97 | } | 97 | } |
| 98 | else | 98 | else |
| 99 | { | 99 | { |
| 100 | break; | 100 | break; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | m_num_entries++; | 103 | m_num_entries++; |
| 104 | last_pos = m_file.tellg(); | 104 | last_pos = m_file.tellg(); |
| 105 | } | 105 | } |
| 106 | m_file.seekp(last_pos); | 106 | m_file.seekp(last_pos); |
| 107 | m_file.clear(); | 107 | m_file.clear(); |
| 108 | 108 | ||
| 109 | delete[] value; | 109 | delete[] value; |
| 110 | return m_num_entries; | 110 | return m_num_entries; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | // failed to open file for reading or bad header | 113 | // failed to open file for reading or bad header |
| 114 | // close and recreate file | 114 | // close and recreate file |
| 115 | Close(); | 115 | Close(); |
| 116 | m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary); | 116 | m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary); |
| 117 | WriteHeader(); | 117 | WriteHeader(); |
| 118 | return 0; | 118 | return 0; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | void Sync() | 121 | void Sync() |
| 122 | { | 122 | { |
| 123 | m_file.flush(); | 123 | m_file.flush(); |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | void Close() | 126 | void Close() |
| 127 | { | 127 | { |
| 128 | if (m_file.is_open()) | 128 | if (m_file.is_open()) |
| 129 | m_file.close(); | 129 | m_file.close(); |
| 130 | // clear any error flags | 130 | // clear any error flags |
| 131 | m_file.clear(); | 131 | m_file.clear(); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | // Appends a key-value pair to the store. | 134 | // Appends a key-value pair to the store. |
| 135 | void Append(const K &key, const V *value, u32 value_size) | 135 | void Append(const K &key, const V *value, u32 value_size) |
| 136 | { | 136 | { |
| 137 | // TODO: Should do a check that we don't already have "key"? (I think each caller does that already.) | 137 | // TODO: Should do a check that we don't already have "key"? (I think each caller does that already.) |
| 138 | Write(&value_size); | 138 | Write(&value_size); |
| 139 | Write(&key); | 139 | Write(&key); |
| 140 | Write(value, value_size); | 140 | Write(value, value_size); |
| 141 | m_num_entries++; | 141 | m_num_entries++; |
| 142 | Write(&m_num_entries); | 142 | Write(&m_num_entries); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | private: | 145 | private: |
| 146 | void WriteHeader() | 146 | void WriteHeader() |
| 147 | { | 147 | { |
| 148 | Write(&m_header); | 148 | Write(&m_header); |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | bool ValidateHeader() | 151 | bool ValidateHeader() |
| 152 | { | 152 | { |
| 153 | char file_header[sizeof(Header)]; | 153 | char file_header[sizeof(Header)]; |
| 154 | 154 | ||
| 155 | return (Read(file_header, sizeof(Header)) | 155 | return (Read(file_header, sizeof(Header)) |
| 156 | && !memcmp((const char*)&m_header, file_header, sizeof(Header))); | 156 | && !memcmp((const char*)&m_header, file_header, sizeof(Header))); |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | template <typename D> | 159 | template <typename D> |
| 160 | bool Write(const D *data, u32 count = 1) | 160 | bool Write(const D *data, u32 count = 1) |
| 161 | { | 161 | { |
| 162 | return m_file.write((const char*)data, count * sizeof(D)).good(); | 162 | return m_file.write((const char*)data, count * sizeof(D)).good(); |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | template <typename D> | 165 | template <typename D> |
| 166 | bool Read(const D *data, u32 count = 1) | 166 | bool Read(const D *data, u32 count = 1) |
| 167 | { | 167 | { |
| 168 | return m_file.read((char*)data, count * sizeof(D)).good(); | 168 | return m_file.read((char*)data, count * sizeof(D)).good(); |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | struct Header | 171 | struct Header |
| 172 | { | 172 | { |
| 173 | Header() | 173 | Header() |
| 174 | : id(*(u32*)"DCAC") | 174 | : id(*(u32*)"DCAC") |
| 175 | , key_t_size(sizeof(K)) | 175 | , key_t_size(sizeof(K)) |
| 176 | , value_t_size(sizeof(V)) | 176 | , value_t_size(sizeof(V)) |
| 177 | { | 177 | { |
| 178 | memcpy(ver, scm_rev_git_str, 40); | 178 | memcpy(ver, scm_rev_git_str, 40); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | const u32 id; | 181 | const u32 id; |
| 182 | const u16 key_t_size, value_t_size; | 182 | const u16 key_t_size, value_t_size; |
| 183 | char ver[40]; | 183 | char ver[40]; |
| 184 | 184 | ||
| 185 | } m_header; | 185 | } m_header; |
| 186 | 186 | ||
| 187 | std::fstream m_file; | 187 | std::fstream m_file; |
| 188 | u32 m_num_entries; | 188 | u32 m_num_entries; |
| 189 | }; | 189 | }; |
| 190 | 190 | ||
| 191 | #endif // _LINEAR_DISKCACHE | 191 | #endif // _LINEAR_DISKCACHE |
diff --git a/src/common/src/log.h b/src/common/src/log.h index 7cd99ba8d..9b2da5016 100644 --- a/src/common/src/log.h +++ b/src/common/src/log.h | |||
| @@ -5,74 +5,74 @@ | |||
| 5 | #ifndef _LOG_H_ | 5 | #ifndef _LOG_H_ |
| 6 | #define _LOG_H_ | 6 | #define _LOG_H_ |
| 7 | 7 | ||
| 8 | #define NOTICE_LEVEL 1 // VERY important information that is NOT errors. Like startup and OSReports. | 8 | #define NOTICE_LEVEL 1 // VERY important information that is NOT errors. Like startup and OSReports. |
| 9 | #define ERROR_LEVEL 2 // Critical errors | 9 | #define ERROR_LEVEL 2 // Critical errors |
| 10 | #define WARNING_LEVEL 3 // Something is suspicious. | 10 | #define WARNING_LEVEL 3 // Something is suspicious. |
| 11 | #define INFO_LEVEL 4 // General information. | 11 | #define INFO_LEVEL 4 // General information. |
| 12 | #define DEBUG_LEVEL 5 // Detailed debugging - might make things slow. | 12 | #define DEBUG_LEVEL 5 // Detailed debugging - might make things slow. |
| 13 | 13 | ||
| 14 | namespace LogTypes | 14 | namespace LogTypes |
| 15 | { | 15 | { |
| 16 | 16 | ||
| 17 | enum LOG_TYPE { | 17 | enum LOG_TYPE { |
| 18 | ACTIONREPLAY, | 18 | ACTIONREPLAY, |
| 19 | AUDIO, | 19 | AUDIO, |
| 20 | AUDIO_INTERFACE, | 20 | AUDIO_INTERFACE, |
| 21 | BOOT, | 21 | BOOT, |
| 22 | COMMANDPROCESSOR, | 22 | COMMANDPROCESSOR, |
| 23 | COMMON, | 23 | COMMON, |
| 24 | CONSOLE, | 24 | CONSOLE, |
| 25 | DISCIO, | 25 | DISCIO, |
| 26 | FILEMON, | 26 | FILEMON, |
| 27 | DSPHLE, | 27 | DSPHLE, |
| 28 | DSPLLE, | 28 | DSPLLE, |
| 29 | DSP_MAIL, | 29 | DSP_MAIL, |
| 30 | DSPINTERFACE, | 30 | DSPINTERFACE, |
| 31 | DVDINTERFACE, | 31 | DVDINTERFACE, |
| 32 | DYNA_REC, | 32 | DYNA_REC, |
| 33 | EXPANSIONINTERFACE, | 33 | EXPANSIONINTERFACE, |
| 34 | GDB_STUB, | 34 | GDB_STUB, |
| 35 | ARM11, | 35 | ARM11, |
| 36 | GPFIFO, | 36 | GPFIFO, |
| 37 | OSHLE, | 37 | OSHLE, |
| 38 | MASTER_LOG, | 38 | MASTER_LOG, |
| 39 | MEMMAP, | 39 | MEMMAP, |
| 40 | MEMCARD_MANAGER, | 40 | MEMCARD_MANAGER, |
| 41 | OSREPORT, | 41 | OSREPORT, |
| 42 | PAD, | 42 | PAD, |
| 43 | PROCESSORINTERFACE, | 43 | PROCESSORINTERFACE, |
| 44 | PIXELENGINE, | 44 | PIXELENGINE, |
| 45 | SERIALINTERFACE, | 45 | SERIALINTERFACE, |
| 46 | SP1, | 46 | SP1, |
| 47 | STREAMINGINTERFACE, | 47 | STREAMINGINTERFACE, |
| 48 | VIDEO, | 48 | VIDEO, |
| 49 | VIDEOINTERFACE, | 49 | VIDEOINTERFACE, |
| 50 | LOADER, | 50 | LOADER, |
| 51 | FILESYS, | 51 | FILESYS, |
| 52 | WII_IPC_DVD, | 52 | WII_IPC_DVD, |
| 53 | WII_IPC_ES, | 53 | WII_IPC_ES, |
| 54 | WII_IPC_FILEIO, | 54 | WII_IPC_FILEIO, |
| 55 | WII_IPC_HID, | 55 | WII_IPC_HID, |
| 56 | WII_IPC_HLE, | 56 | WII_IPC_HLE, |
| 57 | WII_IPC_NET, | 57 | WII_IPC_NET, |
| 58 | WII_IPC_WC24, | 58 | WII_IPC_WC24, |
| 59 | WII_IPC_SSL, | 59 | WII_IPC_SSL, |
| 60 | WII_IPC_SD, | 60 | WII_IPC_SD, |
| 61 | WII_IPC_STM, | 61 | WII_IPC_STM, |
| 62 | WII_IPC_WIIMOTE, | 62 | WII_IPC_WIIMOTE, |
| 63 | TIME, | 63 | TIME, |
| 64 | NETPLAY, | 64 | NETPLAY, |
| 65 | 65 | ||
| 66 | NUMBER_OF_LOGS // Must be last | 66 | NUMBER_OF_LOGS // Must be last |
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | // FIXME: should this be removed? | 69 | // FIXME: should this be removed? |
| 70 | enum LOG_LEVELS { | 70 | enum LOG_LEVELS { |
| 71 | LNOTICE = NOTICE_LEVEL, | 71 | LNOTICE = NOTICE_LEVEL, |
| 72 | LERROR = ERROR_LEVEL, | 72 | LERROR = ERROR_LEVEL, |
| 73 | LWARNING = WARNING_LEVEL, | 73 | LWARNING = WARNING_LEVEL, |
| 74 | LINFO = INFO_LEVEL, | 74 | LINFO = INFO_LEVEL, |
| 75 | LDEBUG = DEBUG_LEVEL, | 75 | LDEBUG = DEBUG_LEVEL, |
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| 78 | #define LOGTYPES_LEVELS LogTypes::LOG_LEVELS | 78 | #define LOGTYPES_LEVELS LogTypes::LOG_LEVELS |
| @@ -81,11 +81,11 @@ enum LOG_LEVELS { | |||
| 81 | } // namespace | 81 | } // namespace |
| 82 | 82 | ||
| 83 | void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, | 83 | void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, |
| 84 | const char *file, int line, const char *fmt, ...) | 84 | const char *file, int line, const char *fmt, ...) |
| 85 | #ifdef __GNUC__ | 85 | #ifdef __GNUC__ |
| 86 | __attribute__((format(printf, 5, 6))) | 86 | __attribute__((format(printf, 5, 6))) |
| 87 | #endif | 87 | #endif |
| 88 | ; | 88 | ; |
| 89 | 89 | ||
| 90 | #if defined LOGGING || defined _DEBUG || defined DEBUGFAST | 90 | #if defined LOGGING || defined _DEBUG || defined DEBUGFAST |
| 91 | #define MAX_LOGLEVEL DEBUG_LEVEL | 91 | #define MAX_LOGLEVEL DEBUG_LEVEL |
| @@ -100,9 +100,9 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, | |||
| 100 | #else | 100 | #else |
| 101 | // Let the compiler optimize this out | 101 | // Let the compiler optimize this out |
| 102 | #define GENERIC_LOG(t, v, ...) { \ | 102 | #define GENERIC_LOG(t, v, ...) { \ |
| 103 | if (v <= MAX_LOGLEVEL) \ | 103 | if (v <= MAX_LOGLEVEL) \ |
| 104 | GenericLog(v, t, __FILE__, __LINE__, __VA_ARGS__); \ | 104 | GenericLog(v, t, __FILE__, __LINE__, __VA_ARGS__); \ |
| 105 | } | 105 | } |
| 106 | #endif | 106 | #endif |
| 107 | 107 | ||
| 108 | #define ERROR_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LERROR, __VA_ARGS__) } while (0) | 108 | #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, | |||
| 113 | 113 | ||
| 114 | #if MAX_LOGLEVEL >= DEBUG_LEVEL | 114 | #if MAX_LOGLEVEL >= DEBUG_LEVEL |
| 115 | #define _dbg_assert_(_t_, _a_) \ | 115 | #define _dbg_assert_(_t_, _a_) \ |
| 116 | if (!(_a_)) {\ | 116 | if (!(_a_)) {\ |
| 117 | ERROR_LOG(_t_, "Error...\n\n Line: %d\n File: %s\n Time: %s\n\nIgnore and continue?", \ | 117 | ERROR_LOG(_t_, "Error...\n\n Line: %d\n File: %s\n Time: %s\n\nIgnore and continue?", \ |
| 118 | __LINE__, __FILE__, __TIME__); \ | 118 | __LINE__, __FILE__, __TIME__); \ |
| 119 | if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \ | 119 | if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \ |
| 120 | } | 120 | } |
| 121 | #define _dbg_assert_msg_(_t_, _a_, ...)\ | 121 | #define _dbg_assert_msg_(_t_, _a_, ...)\ |
| 122 | if (!(_a_)) {\ | 122 | if (!(_a_)) {\ |
| 123 | ERROR_LOG(_t_, __VA_ARGS__); \ | 123 | ERROR_LOG(_t_, __VA_ARGS__); \ |
| 124 | if (!PanicYesNo(__VA_ARGS__)) {Crash();} \ | 124 | if (!PanicYesNo(__VA_ARGS__)) {Crash();} \ |
| 125 | } | 125 | } |
| 126 | #define _dbg_update_() Host_UpdateLogDisplay(); | 126 | #define _dbg_update_() Host_UpdateLogDisplay(); |
| 127 | 127 | ||
| 128 | #else // not debug | 128 | #else // not debug |
| @@ -138,15 +138,15 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, | |||
| 138 | 138 | ||
| 139 | #ifndef GEKKO | 139 | #ifndef GEKKO |
| 140 | #ifdef _WIN32 | 140 | #ifdef _WIN32 |
| 141 | #define _assert_msg_(_t_, _a_, _fmt_, ...) \ | 141 | #define _assert_msg_(_t_, _a_, _fmt_, ...) \ |
| 142 | if (!(_a_)) {\ | 142 | if (!(_a_)) {\ |
| 143 | if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \ | 143 | if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \ |
| 144 | } | 144 | } |
| 145 | #else // not win32 | 145 | #else // not win32 |
| 146 | #define _assert_msg_(_t_, _a_, _fmt_, ...) \ | 146 | #define _assert_msg_(_t_, _a_, _fmt_, ...) \ |
| 147 | if (!(_a_)) {\ | 147 | if (!(_a_)) {\ |
| 148 | if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \ | 148 | if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \ |
| 149 | } | 149 | } |
| 150 | #endif // WIN32 | 150 | #endif // WIN32 |
| 151 | #else // GEKKO | 151 | #else // GEKKO |
| 152 | #define _assert_msg_(_t_, _a_, _fmt_, ...) | 152 | #define _assert_msg_(_t_, _a_, _fmt_, ...) |
diff --git a/src/common/src/log_manager.cpp b/src/common/src/log_manager.cpp index 8d6a972a9..8c8828e8c 100644 --- a/src/common/src/log_manager.cpp +++ b/src/common/src/log_manager.cpp | |||
| @@ -14,187 +14,187 @@ | |||
| 14 | #include "file_util.h" | 14 | #include "file_util.h" |
| 15 | 15 | ||
| 16 | void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, | 16 | void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, |
| 17 | const char *file, int line, const char* fmt, ...) | 17 | const char *file, int line, const char* fmt, ...) |
| 18 | { | 18 | { |
| 19 | va_list args; | 19 | va_list args; |
| 20 | va_start(args, fmt); | 20 | va_start(args, fmt); |
| 21 | if (LogManager::GetInstance()) | 21 | if (LogManager::GetInstance()) |
| 22 | LogManager::GetInstance()->Log(level, type, | 22 | LogManager::GetInstance()->Log(level, type, |
| 23 | file, line, fmt, args); | 23 | file, line, fmt, args); |
| 24 | va_end(args); | 24 | va_end(args); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | LogManager *LogManager::m_logManager = NULL; | 27 | LogManager *LogManager::m_logManager = NULL; |
| 28 | 28 | ||
| 29 | LogManager::LogManager() | 29 | LogManager::LogManager() |
| 30 | { | 30 | { |
| 31 | // create log files | 31 | // create log files |
| 32 | m_Log[LogTypes::MASTER_LOG] = new LogContainer("*", "Master Log"); | 32 | m_Log[LogTypes::MASTER_LOG] = new LogContainer("*", "Master Log"); |
| 33 | m_Log[LogTypes::BOOT] = new LogContainer("BOOT", "Boot"); | 33 | m_Log[LogTypes::BOOT] = new LogContainer("BOOT", "Boot"); |
| 34 | m_Log[LogTypes::COMMON] = new LogContainer("COMMON", "Common"); | 34 | m_Log[LogTypes::COMMON] = new LogContainer("COMMON", "Common"); |
| 35 | m_Log[LogTypes::DISCIO] = new LogContainer("DIO", "Disc IO"); | 35 | m_Log[LogTypes::DISCIO] = new LogContainer("DIO", "Disc IO"); |
| 36 | m_Log[LogTypes::FILEMON] = new LogContainer("FileMon", "File Monitor"); | 36 | m_Log[LogTypes::FILEMON] = new LogContainer("FileMon", "File Monitor"); |
| 37 | m_Log[LogTypes::PAD] = new LogContainer("PAD", "Pad"); | 37 | m_Log[LogTypes::PAD] = new LogContainer("PAD", "Pad"); |
| 38 | m_Log[LogTypes::PIXELENGINE] = new LogContainer("PE", "PixelEngine"); | 38 | m_Log[LogTypes::PIXELENGINE] = new LogContainer("PE", "PixelEngine"); |
| 39 | m_Log[LogTypes::COMMANDPROCESSOR] = new LogContainer("CP", "CommandProc"); | 39 | m_Log[LogTypes::COMMANDPROCESSOR] = new LogContainer("CP", "CommandProc"); |
| 40 | m_Log[LogTypes::VIDEOINTERFACE] = new LogContainer("VI", "VideoInt"); | 40 | m_Log[LogTypes::VIDEOINTERFACE] = new LogContainer("VI", "VideoInt"); |
| 41 | m_Log[LogTypes::SERIALINTERFACE] = new LogContainer("SI", "SerialInt"); | 41 | m_Log[LogTypes::SERIALINTERFACE] = new LogContainer("SI", "SerialInt"); |
| 42 | m_Log[LogTypes::PROCESSORINTERFACE] = new LogContainer("PI", "ProcessorInt"); | 42 | m_Log[LogTypes::PROCESSORINTERFACE] = new LogContainer("PI", "ProcessorInt"); |
| 43 | m_Log[LogTypes::MEMMAP] = new LogContainer("MI", "MI & memmap"); | 43 | m_Log[LogTypes::MEMMAP] = new LogContainer("MI", "MI & memmap"); |
| 44 | m_Log[LogTypes::SP1] = new LogContainer("SP1", "Serial Port 1"); | 44 | m_Log[LogTypes::SP1] = new LogContainer("SP1", "Serial Port 1"); |
| 45 | m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream", "StreamingInt"); | 45 | m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream", "StreamingInt"); |
| 46 | m_Log[LogTypes::DSPINTERFACE] = new LogContainer("DSP", "DSPInterface"); | 46 | m_Log[LogTypes::DSPINTERFACE] = new LogContainer("DSP", "DSPInterface"); |
| 47 | m_Log[LogTypes::DVDINTERFACE] = new LogContainer("DVD", "DVDInterface"); | 47 | m_Log[LogTypes::DVDINTERFACE] = new LogContainer("DVD", "DVDInterface"); |
| 48 | m_Log[LogTypes::GPFIFO] = new LogContainer("GP", "GPFifo"); | 48 | m_Log[LogTypes::GPFIFO] = new LogContainer("GP", "GPFifo"); |
| 49 | m_Log[LogTypes::EXPANSIONINTERFACE] = new LogContainer("EXI", "ExpansionInt"); | 49 | m_Log[LogTypes::EXPANSIONINTERFACE] = new LogContainer("EXI", "ExpansionInt"); |
| 50 | m_Log[LogTypes::GDB_STUB] = new LogContainer("GDB_STUB", "GDB Stub"); | 50 | m_Log[LogTypes::GDB_STUB] = new LogContainer("GDB_STUB", "GDB Stub"); |
| 51 | m_Log[LogTypes::AUDIO_INTERFACE] = new LogContainer("AI", "AudioInt"); | 51 | m_Log[LogTypes::AUDIO_INTERFACE] = new LogContainer("AI", "AudioInt"); |
| 52 | m_Log[LogTypes::ARM11] = new LogContainer("ARM11", "ARM11"); | 52 | m_Log[LogTypes::ARM11] = new LogContainer("ARM11", "ARM11"); |
| 53 | m_Log[LogTypes::OSHLE] = new LogContainer("HLE", "HLE"); | 53 | m_Log[LogTypes::OSHLE] = new LogContainer("HLE", "HLE"); |
| 54 | m_Log[LogTypes::DSPHLE] = new LogContainer("DSPHLE", "DSP HLE"); | 54 | m_Log[LogTypes::DSPHLE] = new LogContainer("DSPHLE", "DSP HLE"); |
| 55 | m_Log[LogTypes::DSPLLE] = new LogContainer("DSPLLE", "DSP LLE"); | 55 | m_Log[LogTypes::DSPLLE] = new LogContainer("DSPLLE", "DSP LLE"); |
| 56 | m_Log[LogTypes::DSP_MAIL] = new LogContainer("DSPMails", "DSP Mails"); | 56 | m_Log[LogTypes::DSP_MAIL] = new LogContainer("DSPMails", "DSP Mails"); |
| 57 | m_Log[LogTypes::VIDEO] = new LogContainer("Video", "Video Backend"); | 57 | m_Log[LogTypes::VIDEO] = new LogContainer("Video", "Video Backend"); |
| 58 | m_Log[LogTypes::AUDIO] = new LogContainer("Audio", "Audio Emulator"); | 58 | m_Log[LogTypes::AUDIO] = new LogContainer("Audio", "Audio Emulator"); |
| 59 | m_Log[LogTypes::DYNA_REC] = new LogContainer("JIT", "Dynamic Recompiler"); | 59 | m_Log[LogTypes::DYNA_REC] = new LogContainer("JIT", "Dynamic Recompiler"); |
| 60 | m_Log[LogTypes::CONSOLE] = new LogContainer("CONSOLE", "Dolphin Console"); | 60 | m_Log[LogTypes::CONSOLE] = new LogContainer("CONSOLE", "Dolphin Console"); |
| 61 | m_Log[LogTypes::OSREPORT] = new LogContainer("OSREPORT", "OSReport"); | 61 | m_Log[LogTypes::OSREPORT] = new LogContainer("OSREPORT", "OSReport"); |
| 62 | m_Log[LogTypes::TIME] = new LogContainer("Time", "Core Timing"); | 62 | m_Log[LogTypes::TIME] = new LogContainer("Time", "Core Timing"); |
| 63 | m_Log[LogTypes::LOADER] = new LogContainer("Loader", "Loader"); | 63 | m_Log[LogTypes::LOADER] = new LogContainer("Loader", "Loader"); |
| 64 | m_Log[LogTypes::FILESYS] = new LogContainer("FileSys", "File System"); | 64 | m_Log[LogTypes::FILESYS] = new LogContainer("FileSys", "File System"); |
| 65 | m_Log[LogTypes::WII_IPC_HID] = new LogContainer("WII_IPC_HID", "WII IPC HID"); | 65 | m_Log[LogTypes::WII_IPC_HID] = new LogContainer("WII_IPC_HID", "WII IPC HID"); |
| 66 | m_Log[LogTypes::WII_IPC_HLE] = new LogContainer("WII_IPC_HLE", "WII IPC HLE"); | 66 | m_Log[LogTypes::WII_IPC_HLE] = new LogContainer("WII_IPC_HLE", "WII IPC HLE"); |
| 67 | m_Log[LogTypes::WII_IPC_DVD] = new LogContainer("WII_IPC_DVD", "WII IPC DVD"); | 67 | m_Log[LogTypes::WII_IPC_DVD] = new LogContainer("WII_IPC_DVD", "WII IPC DVD"); |
| 68 | m_Log[LogTypes::WII_IPC_ES] = new LogContainer("WII_IPC_ES", "WII IPC ES"); | 68 | m_Log[LogTypes::WII_IPC_ES] = new LogContainer("WII_IPC_ES", "WII IPC ES"); |
| 69 | m_Log[LogTypes::WII_IPC_FILEIO] = new LogContainer("WII_IPC_FILEIO","WII IPC FILEIO"); | 69 | m_Log[LogTypes::WII_IPC_FILEIO] = new LogContainer("WII_IPC_FILEIO","WII IPC FILEIO"); |
| 70 | m_Log[LogTypes::WII_IPC_SD] = new LogContainer("WII_IPC_SD", "WII IPC SD"); | 70 | m_Log[LogTypes::WII_IPC_SD] = new LogContainer("WII_IPC_SD", "WII IPC SD"); |
| 71 | m_Log[LogTypes::WII_IPC_STM] = new LogContainer("WII_IPC_STM", "WII IPC STM"); | 71 | m_Log[LogTypes::WII_IPC_STM] = new LogContainer("WII_IPC_STM", "WII IPC STM"); |
| 72 | m_Log[LogTypes::WII_IPC_NET] = new LogContainer("WII_IPC_NET", "WII IPC NET"); | 72 | m_Log[LogTypes::WII_IPC_NET] = new LogContainer("WII_IPC_NET", "WII IPC NET"); |
| 73 | m_Log[LogTypes::WII_IPC_WC24] = new LogContainer("WII_IPC_WC24", "WII IPC WC24"); | 73 | m_Log[LogTypes::WII_IPC_WC24] = new LogContainer("WII_IPC_WC24", "WII IPC WC24"); |
| 74 | m_Log[LogTypes::WII_IPC_SSL] = new LogContainer("WII_IPC_SSL", "WII IPC SSL"); | 74 | m_Log[LogTypes::WII_IPC_SSL] = new LogContainer("WII_IPC_SSL", "WII IPC SSL"); |
| 75 | m_Log[LogTypes::WII_IPC_WIIMOTE] = new LogContainer("WII_IPC_WIIMOTE","WII IPC WIIMOTE"); | 75 | m_Log[LogTypes::WII_IPC_WIIMOTE] = new LogContainer("WII_IPC_WIIMOTE","WII IPC WIIMOTE"); |
| 76 | m_Log[LogTypes::ACTIONREPLAY] = new LogContainer("ActionReplay", "ActionReplay"); | 76 | m_Log[LogTypes::ACTIONREPLAY] = new LogContainer("ActionReplay", "ActionReplay"); |
| 77 | m_Log[LogTypes::MEMCARD_MANAGER] = new LogContainer("MemCard Manager", "MemCard Manager"); | 77 | m_Log[LogTypes::MEMCARD_MANAGER] = new LogContainer("MemCard Manager", "MemCard Manager"); |
| 78 | m_Log[LogTypes::NETPLAY] = new LogContainer("NETPLAY", "Netplay"); | 78 | m_Log[LogTypes::NETPLAY] = new LogContainer("NETPLAY", "Netplay"); |
| 79 | 79 | ||
| 80 | m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str()); | 80 | m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str()); |
| 81 | m_consoleLog = new ConsoleListener(); | 81 | m_consoleLog = new ConsoleListener(); |
| 82 | m_debuggerLog = new DebuggerLogListener(); | 82 | m_debuggerLog = new DebuggerLogListener(); |
| 83 | 83 | ||
| 84 | for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | 84 | for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) |
| 85 | { | 85 | { |
| 86 | m_Log[i]->SetEnable(true); | 86 | m_Log[i]->SetEnable(true); |
| 87 | m_Log[i]->AddListener(m_fileLog); | 87 | m_Log[i]->AddListener(m_fileLog); |
| 88 | m_Log[i]->AddListener(m_consoleLog); | 88 | m_Log[i]->AddListener(m_consoleLog); |
| 89 | #ifdef _MSC_VER | 89 | #ifdef _MSC_VER |
| 90 | if (IsDebuggerPresent()) | 90 | if (IsDebuggerPresent()) |
| 91 | m_Log[i]->AddListener(m_debuggerLog); | 91 | m_Log[i]->AddListener(m_debuggerLog); |
| 92 | #endif | 92 | #endif |
| 93 | } | 93 | } |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | LogManager::~LogManager() | 96 | LogManager::~LogManager() |
| 97 | { | 97 | { |
| 98 | for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | 98 | for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) |
| 99 | { | 99 | { |
| 100 | m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_fileLog); | 100 | m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_fileLog); |
| 101 | m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog); | 101 | m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog); |
| 102 | m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_debuggerLog); | 102 | m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_debuggerLog); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | 105 | for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) |
| 106 | delete m_Log[i]; | 106 | delete m_Log[i]; |
| 107 | 107 | ||
| 108 | delete m_fileLog; | 108 | delete m_fileLog; |
| 109 | delete m_consoleLog; | 109 | delete m_consoleLog; |
| 110 | delete m_debuggerLog; | 110 | delete m_debuggerLog; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, | 113 | void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, |
| 114 | const char *file, int line, const char *format, va_list args) | 114 | const char *file, int line, const char *format, va_list args) |
| 115 | { | 115 | { |
| 116 | char temp[MAX_MSGLEN]; | 116 | char temp[MAX_MSGLEN]; |
| 117 | char msg[MAX_MSGLEN * 2]; | 117 | char msg[MAX_MSGLEN * 2]; |
| 118 | LogContainer *log = m_Log[type]; | 118 | LogContainer *log = m_Log[type]; |
| 119 | 119 | ||
| 120 | if (!log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners()) | 120 | if (!log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners()) |
| 121 | return; | 121 | return; |
| 122 | 122 | ||
| 123 | CharArrayFromFormatV(temp, MAX_MSGLEN, format, args); | 123 | CharArrayFromFormatV(temp, MAX_MSGLEN, format, args); |
| 124 | 124 | ||
| 125 | static const char level_to_char[7] = "-NEWID"; | 125 | static const char level_to_char[7] = "-NEWID"; |
| 126 | sprintf(msg, "%s %s:%u %c[%s]: %s\n", | 126 | sprintf(msg, "%s %s:%u %c[%s]: %s\n", |
| 127 | Common::Timer::GetTimeFormatted().c_str(), | 127 | Common::Timer::GetTimeFormatted().c_str(), |
| 128 | file, line, level_to_char[(int)level], | 128 | file, line, level_to_char[(int)level], |
| 129 | log->GetShortName(), temp); | 129 | log->GetShortName(), temp); |
| 130 | #ifdef ANDROID | 130 | #ifdef ANDROID |
| 131 | Host_SysMessage(msg); | 131 | Host_SysMessage(msg); |
| 132 | #endif | 132 | #endif |
| 133 | printf(msg); // TODO(ShizZy): RemoveMe when I no longer need this | 133 | printf(msg); // TODO(ShizZy): RemoveMe when I no longer need this |
| 134 | log->Trigger(level, msg); | 134 | log->Trigger(level, msg); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | void LogManager::Init() | 137 | void LogManager::Init() |
| 138 | { | 138 | { |
| 139 | m_logManager = new LogManager(); | 139 | m_logManager = new LogManager(); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | void LogManager::Shutdown() | 142 | void LogManager::Shutdown() |
| 143 | { | 143 | { |
| 144 | delete m_logManager; | 144 | delete m_logManager; |
| 145 | m_logManager = NULL; | 145 | m_logManager = NULL; |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | LogContainer::LogContainer(const char* shortName, const char* fullName, bool enable) | 148 | LogContainer::LogContainer(const char* shortName, const char* fullName, bool enable) |
| 149 | : m_enable(enable) | 149 | : m_enable(enable) |
| 150 | { | 150 | { |
| 151 | strncpy(m_fullName, fullName, 128); | 151 | strncpy(m_fullName, fullName, 128); |
| 152 | strncpy(m_shortName, shortName, 32); | 152 | strncpy(m_shortName, shortName, 32); |
| 153 | m_level = LogTypes::LWARNING; | 153 | m_level = LogTypes::LWARNING; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | // LogContainer | 156 | // LogContainer |
| 157 | void LogContainer::AddListener(LogListener *listener) | 157 | void LogContainer::AddListener(LogListener *listener) |
| 158 | { | 158 | { |
| 159 | std::lock_guard<std::mutex> lk(m_listeners_lock); | 159 | std::lock_guard<std::mutex> lk(m_listeners_lock); |
| 160 | m_listeners.insert(listener); | 160 | m_listeners.insert(listener); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | void LogContainer::RemoveListener(LogListener *listener) | 163 | void LogContainer::RemoveListener(LogListener *listener) |
| 164 | { | 164 | { |
| 165 | std::lock_guard<std::mutex> lk(m_listeners_lock); | 165 | std::lock_guard<std::mutex> lk(m_listeners_lock); |
| 166 | m_listeners.erase(listener); | 166 | m_listeners.erase(listener); |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | void LogContainer::Trigger(LogTypes::LOG_LEVELS level, const char *msg) | 169 | void LogContainer::Trigger(LogTypes::LOG_LEVELS level, const char *msg) |
| 170 | { | 170 | { |
| 171 | std::lock_guard<std::mutex> lk(m_listeners_lock); | 171 | std::lock_guard<std::mutex> lk(m_listeners_lock); |
| 172 | 172 | ||
| 173 | std::set<LogListener*>::const_iterator i; | 173 | std::set<LogListener*>::const_iterator i; |
| 174 | for (i = m_listeners.begin(); i != m_listeners.end(); ++i) | 174 | for (i = m_listeners.begin(); i != m_listeners.end(); ++i) |
| 175 | { | 175 | { |
| 176 | (*i)->Log(level, msg); | 176 | (*i)->Log(level, msg); |
| 177 | } | 177 | } |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | FileLogListener::FileLogListener(const char *filename) | 180 | FileLogListener::FileLogListener(const char *filename) |
| 181 | { | 181 | { |
| 182 | OpenFStream(m_logfile, filename, std::ios::app); | 182 | OpenFStream(m_logfile, filename, std::ios::app); |
| 183 | SetEnable(true); | 183 | SetEnable(true); |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) | 186 | void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) |
| 187 | { | 187 | { |
| 188 | if (!IsEnabled() || !IsValid()) | 188 | if (!IsEnabled() || !IsValid()) |
| 189 | return; | 189 | return; |
| 190 | 190 | ||
| 191 | std::lock_guard<std::mutex> lk(m_log_lock); | 191 | std::lock_guard<std::mutex> lk(m_log_lock); |
| 192 | m_logfile << msg << std::flush; | 192 | m_logfile << msg << std::flush; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | void DebuggerLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) | 195 | void DebuggerLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) |
| 196 | { | 196 | { |
| 197 | #if _MSC_VER | 197 | #if _MSC_VER |
| 198 | ::OutputDebugStringA(msg); | 198 | ::OutputDebugStringA(msg); |
| 199 | #endif | 199 | #endif |
| 200 | } | 200 | } |
diff --git a/src/common/src/log_manager.h b/src/common/src/log_manager.h index 59078849b..579198ff6 100644 --- a/src/common/src/log_manager.h +++ b/src/common/src/log_manager.h | |||
| @@ -21,65 +21,65 @@ | |||
| 21 | class LogListener | 21 | class LogListener |
| 22 | { | 22 | { |
| 23 | public: | 23 | public: |
| 24 | virtual ~LogListener() {} | 24 | virtual ~LogListener() {} |
| 25 | 25 | ||
| 26 | virtual void Log(LogTypes::LOG_LEVELS, const char *msg) = 0; | 26 | virtual void Log(LogTypes::LOG_LEVELS, const char *msg) = 0; |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | class FileLogListener : public LogListener | 29 | class FileLogListener : public LogListener |
| 30 | { | 30 | { |
| 31 | public: | 31 | public: |
| 32 | FileLogListener(const char *filename); | 32 | FileLogListener(const char *filename); |
| 33 | 33 | ||
| 34 | void Log(LogTypes::LOG_LEVELS, const char *msg); | 34 | void Log(LogTypes::LOG_LEVELS, const char *msg); |
| 35 | 35 | ||
| 36 | bool IsValid() { return !m_logfile.fail(); } | 36 | bool IsValid() { return !m_logfile.fail(); } |
| 37 | bool IsEnabled() const { return m_enable; } | 37 | bool IsEnabled() const { return m_enable; } |
| 38 | void SetEnable(bool enable) { m_enable = enable; } | 38 | void SetEnable(bool enable) { m_enable = enable; } |
| 39 | 39 | ||
| 40 | const char* GetName() const { return "file"; } | 40 | const char* GetName() const { return "file"; } |
| 41 | 41 | ||
| 42 | private: | 42 | private: |
| 43 | std::mutex m_log_lock; | 43 | std::mutex m_log_lock; |
| 44 | std::ofstream m_logfile; | 44 | std::ofstream m_logfile; |
| 45 | bool m_enable; | 45 | bool m_enable; |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | class DebuggerLogListener : public LogListener | 48 | class DebuggerLogListener : public LogListener |
| 49 | { | 49 | { |
| 50 | public: | 50 | public: |
| 51 | void Log(LogTypes::LOG_LEVELS, const char *msg); | 51 | void Log(LogTypes::LOG_LEVELS, const char *msg); |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | class LogContainer | 54 | class LogContainer |
| 55 | { | 55 | { |
| 56 | public: | 56 | public: |
| 57 | LogContainer(const char* shortName, const char* fullName, bool enable = false); | 57 | LogContainer(const char* shortName, const char* fullName, bool enable = false); |
| 58 | 58 | ||
| 59 | const char* GetShortName() const { return m_shortName; } | 59 | const char* GetShortName() const { return m_shortName; } |
| 60 | const char* GetFullName() const { return m_fullName; } | 60 | const char* GetFullName() const { return m_fullName; } |
| 61 | 61 | ||
| 62 | void AddListener(LogListener* listener); | 62 | void AddListener(LogListener* listener); |
| 63 | void RemoveListener(LogListener* listener); | 63 | void RemoveListener(LogListener* listener); |
| 64 | 64 | ||
| 65 | void Trigger(LogTypes::LOG_LEVELS, const char *msg); | 65 | void Trigger(LogTypes::LOG_LEVELS, const char *msg); |
| 66 | 66 | ||
| 67 | bool IsEnabled() const { return m_enable; } | 67 | bool IsEnabled() const { return m_enable; } |
| 68 | void SetEnable(bool enable) { m_enable = enable; } | 68 | void SetEnable(bool enable) { m_enable = enable; } |
| 69 | 69 | ||
| 70 | LogTypes::LOG_LEVELS GetLevel() const { return m_level; } | 70 | LogTypes::LOG_LEVELS GetLevel() const { return m_level; } |
| 71 | 71 | ||
| 72 | void SetLevel(LogTypes::LOG_LEVELS level) { m_level = level; } | 72 | void SetLevel(LogTypes::LOG_LEVELS level) { m_level = level; } |
| 73 | 73 | ||
| 74 | bool HasListeners() const { return !m_listeners.empty(); } | 74 | bool HasListeners() const { return !m_listeners.empty(); } |
| 75 | 75 | ||
| 76 | private: | 76 | private: |
| 77 | char m_fullName[128]; | 77 | char m_fullName[128]; |
| 78 | char m_shortName[32]; | 78 | char m_shortName[32]; |
| 79 | bool m_enable; | 79 | bool m_enable; |
| 80 | LogTypes::LOG_LEVELS m_level; | 80 | LogTypes::LOG_LEVELS m_level; |
| 81 | std::mutex m_listeners_lock; | 81 | std::mutex m_listeners_lock; |
| 82 | std::set<LogListener*> m_listeners; | 82 | std::set<LogListener*> m_listeners; |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | class ConsoleListener; | 85 | class ConsoleListener; |
| @@ -87,83 +87,83 @@ class ConsoleListener; | |||
| 87 | class LogManager : NonCopyable | 87 | class LogManager : NonCopyable |
| 88 | { | 88 | { |
| 89 | private: | 89 | private: |
| 90 | LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS]; | 90 | LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS]; |
| 91 | FileLogListener *m_fileLog; | 91 | FileLogListener *m_fileLog; |
| 92 | ConsoleListener *m_consoleLog; | 92 | ConsoleListener *m_consoleLog; |
| 93 | DebuggerLogListener *m_debuggerLog; | 93 | DebuggerLogListener *m_debuggerLog; |
| 94 | static LogManager *m_logManager; // Singleton. Ugh. | 94 | static LogManager *m_logManager; // Singleton. Ugh. |
| 95 | 95 | ||
| 96 | LogManager(); | 96 | LogManager(); |
| 97 | ~LogManager(); | 97 | ~LogManager(); |
| 98 | public: | 98 | public: |
| 99 | 99 | ||
| 100 | static u32 GetMaxLevel() { return MAX_LOGLEVEL; } | 100 | static u32 GetMaxLevel() { return MAX_LOGLEVEL; } |
| 101 | 101 | ||
| 102 | void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, | 102 | void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, |
| 103 | const char *file, int line, const char *fmt, va_list args); | 103 | const char *file, int line, const char *fmt, va_list args); |
| 104 | 104 | ||
| 105 | void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level) | 105 | void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level) |
| 106 | { | 106 | { |
| 107 | m_Log[type]->SetLevel(level); | 107 | m_Log[type]->SetLevel(level); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | void SetEnable(LogTypes::LOG_TYPE type, bool enable) | 110 | void SetEnable(LogTypes::LOG_TYPE type, bool enable) |
| 111 | { | 111 | { |
| 112 | m_Log[type]->SetEnable(enable); | 112 | m_Log[type]->SetEnable(enable); |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | bool IsEnabled(LogTypes::LOG_TYPE type) const | 115 | bool IsEnabled(LogTypes::LOG_TYPE type) const |
| 116 | { | 116 | { |
| 117 | return m_Log[type]->IsEnabled(); | 117 | return m_Log[type]->IsEnabled(); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | const char* GetShortName(LogTypes::LOG_TYPE type) const | 120 | const char* GetShortName(LogTypes::LOG_TYPE type) const |
| 121 | { | 121 | { |
| 122 | return m_Log[type]->GetShortName(); | 122 | return m_Log[type]->GetShortName(); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | const char* GetFullName(LogTypes::LOG_TYPE type) const | 125 | const char* GetFullName(LogTypes::LOG_TYPE type) const |
| 126 | { | 126 | { |
| 127 | return m_Log[type]->GetFullName(); | 127 | return m_Log[type]->GetFullName(); |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | void AddListener(LogTypes::LOG_TYPE type, LogListener *listener) | 130 | void AddListener(LogTypes::LOG_TYPE type, LogListener *listener) |
| 131 | { | 131 | { |
| 132 | m_Log[type]->AddListener(listener); | 132 | m_Log[type]->AddListener(listener); |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener) | 135 | void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener) |
| 136 | { | 136 | { |
| 137 | m_Log[type]->RemoveListener(listener); | 137 | m_Log[type]->RemoveListener(listener); |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | FileLogListener *GetFileListener() const | 140 | FileLogListener *GetFileListener() const |
| 141 | { | 141 | { |
| 142 | return m_fileLog; | 142 | return m_fileLog; |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | ConsoleListener *GetConsoleListener() const | 145 | ConsoleListener *GetConsoleListener() const |
| 146 | { | 146 | { |
| 147 | return m_consoleLog; | 147 | return m_consoleLog; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | DebuggerLogListener *GetDebuggerListener() const | 150 | DebuggerLogListener *GetDebuggerListener() const |
| 151 | { | 151 | { |
| 152 | return m_debuggerLog; | 152 | return m_debuggerLog; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static LogManager* GetInstance() | 155 | static LogManager* GetInstance() |
| 156 | { | 156 | { |
| 157 | return m_logManager; | 157 | return m_logManager; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | static void SetInstance(LogManager *logManager) | 160 | static void SetInstance(LogManager *logManager) |
| 161 | { | 161 | { |
| 162 | m_logManager = logManager; | 162 | m_logManager = logManager; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | static void Init(); | 165 | static void Init(); |
| 166 | static void Shutdown(); | 166 | static void Shutdown(); |
| 167 | }; | 167 | }; |
| 168 | 168 | ||
| 169 | #endif // _LOGMANAGER_H_ | 169 | #endif // _LOGMANAGER_H_ |
diff --git a/src/common/src/math_util.cpp b/src/common/src/math_util.cpp index 6667e078c..da90f8d74 100644 --- a/src/common/src/math_util.cpp +++ b/src/common/src/math_util.cpp | |||
| @@ -14,82 +14,82 @@ namespace MathUtil | |||
| 14 | 14 | ||
| 15 | u32 ClassifyDouble(double dvalue) | 15 | u32 ClassifyDouble(double dvalue) |
| 16 | { | 16 | { |
| 17 | // TODO: Optimize the below to be as fast as possible. | 17 | // TODO: Optimize the below to be as fast as possible. |
| 18 | IntDouble value; | 18 | IntDouble value; |
| 19 | value.d = dvalue; | 19 | value.d = dvalue; |
| 20 | u64 sign = value.i & DOUBLE_SIGN; | 20 | u64 sign = value.i & DOUBLE_SIGN; |
| 21 | u64 exp = value.i & DOUBLE_EXP; | 21 | u64 exp = value.i & DOUBLE_EXP; |
| 22 | if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP) | 22 | if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP) |
| 23 | { | 23 | { |
| 24 | // Nice normalized number. | 24 | // Nice normalized number. |
| 25 | return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; | 25 | return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; |
| 26 | } | 26 | } |
| 27 | else | 27 | else |
| 28 | { | 28 | { |
| 29 | u64 mantissa = value.i & DOUBLE_FRAC; | 29 | u64 mantissa = value.i & DOUBLE_FRAC; |
| 30 | if (mantissa) | 30 | if (mantissa) |
| 31 | { | 31 | { |
| 32 | if (exp) | 32 | if (exp) |
| 33 | { | 33 | { |
| 34 | return PPC_FPCLASS_QNAN; | 34 | return PPC_FPCLASS_QNAN; |
| 35 | } | 35 | } |
| 36 | else | 36 | else |
| 37 | { | 37 | { |
| 38 | // Denormalized number. | 38 | // Denormalized number. |
| 39 | return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; | 39 | return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; |
| 40 | } | 40 | } |
| 41 | } | 41 | } |
| 42 | else if (exp) | 42 | else if (exp) |
| 43 | { | 43 | { |
| 44 | //Infinite | 44 | //Infinite |
| 45 | return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; | 45 | return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; |
| 46 | } | 46 | } |
| 47 | else | 47 | else |
| 48 | { | 48 | { |
| 49 | //Zero | 49 | //Zero |
| 50 | return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; | 50 | return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; |
| 51 | } | 51 | } |
| 52 | } | 52 | } |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | u32 ClassifyFloat(float fvalue) | 55 | u32 ClassifyFloat(float fvalue) |
| 56 | { | 56 | { |
| 57 | // TODO: Optimize the below to be as fast as possible. | 57 | // TODO: Optimize the below to be as fast as possible. |
| 58 | IntFloat value; | 58 | IntFloat value; |
| 59 | value.f = fvalue; | 59 | value.f = fvalue; |
| 60 | u32 sign = value.i & FLOAT_SIGN; | 60 | u32 sign = value.i & FLOAT_SIGN; |
| 61 | u32 exp = value.i & FLOAT_EXP; | 61 | u32 exp = value.i & FLOAT_EXP; |
| 62 | if (exp > FLOAT_ZERO && exp < FLOAT_EXP) | 62 | if (exp > FLOAT_ZERO && exp < FLOAT_EXP) |
| 63 | { | 63 | { |
| 64 | // Nice normalized number. | 64 | // Nice normalized number. |
| 65 | return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; | 65 | return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; |
| 66 | } | 66 | } |
| 67 | else | 67 | else |
| 68 | { | 68 | { |
| 69 | u32 mantissa = value.i & FLOAT_FRAC; | 69 | u32 mantissa = value.i & FLOAT_FRAC; |
| 70 | if (mantissa) | 70 | if (mantissa) |
| 71 | { | 71 | { |
| 72 | if (exp) | 72 | if (exp) |
| 73 | { | 73 | { |
| 74 | return PPC_FPCLASS_QNAN; // Quiet NAN | 74 | return PPC_FPCLASS_QNAN; // Quiet NAN |
| 75 | } | 75 | } |
| 76 | else | 76 | else |
| 77 | { | 77 | { |
| 78 | // Denormalized number. | 78 | // Denormalized number. |
| 79 | return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; | 79 | return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; |
| 80 | } | 80 | } |
| 81 | } | 81 | } |
| 82 | else if (exp) | 82 | else if (exp) |
| 83 | { | 83 | { |
| 84 | // Infinite | 84 | // Infinite |
| 85 | return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; | 85 | return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; |
| 86 | } | 86 | } |
| 87 | else | 87 | else |
| 88 | { | 88 | { |
| 89 | //Zero | 89 | //Zero |
| 90 | return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; | 90 | return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; |
| 91 | } | 91 | } |
| 92 | } | 92 | } |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | 95 | ||
| @@ -97,116 +97,116 @@ u32 ClassifyFloat(float fvalue) | |||
| 97 | 97 | ||
| 98 | inline void MatrixMul(int n, const float *a, const float *b, float *result) | 98 | inline void MatrixMul(int n, const float *a, const float *b, float *result) |
| 99 | { | 99 | { |
| 100 | for (int i = 0; i < n; ++i) | 100 | for (int i = 0; i < n; ++i) |
| 101 | { | 101 | { |
| 102 | for (int j = 0; j < n; ++j) | 102 | for (int j = 0; j < n; ++j) |
| 103 | { | 103 | { |
| 104 | float temp = 0; | 104 | float temp = 0; |
| 105 | for (int k = 0; k < n; ++k) | 105 | for (int k = 0; k < n; ++k) |
| 106 | { | 106 | { |
| 107 | temp += a[i * n + k] * b[k * n + j]; | 107 | temp += a[i * n + k] * b[k * n + j]; |
| 108 | } | 108 | } |
| 109 | result[i * n + j] = temp; | 109 | result[i * n + j] = temp; |
| 110 | } | 110 | } |
| 111 | } | 111 | } |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | // Calculate sum of a float list | 114 | // Calculate sum of a float list |
| 115 | float MathFloatVectorSum(const std::vector<float>& Vec) | 115 | float MathFloatVectorSum(const std::vector<float>& Vec) |
| 116 | { | 116 | { |
| 117 | return std::accumulate(Vec.begin(), Vec.end(), 0.0f); | 117 | return std::accumulate(Vec.begin(), Vec.end(), 0.0f); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | void Matrix33::LoadIdentity(Matrix33 &mtx) | 120 | void Matrix33::LoadIdentity(Matrix33 &mtx) |
| 121 | { | 121 | { |
| 122 | memset(mtx.data, 0, sizeof(mtx.data)); | 122 | memset(mtx.data, 0, sizeof(mtx.data)); |
| 123 | mtx.data[0] = 1.0f; | 123 | mtx.data[0] = 1.0f; |
| 124 | mtx.data[4] = 1.0f; | 124 | mtx.data[4] = 1.0f; |
| 125 | mtx.data[8] = 1.0f; | 125 | mtx.data[8] = 1.0f; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | void Matrix33::RotateX(Matrix33 &mtx, float rad) | 128 | void Matrix33::RotateX(Matrix33 &mtx, float rad) |
| 129 | { | 129 | { |
| 130 | float s = sin(rad); | 130 | float s = sin(rad); |
| 131 | float c = cos(rad); | 131 | float c = cos(rad); |
| 132 | memset(mtx.data, 0, sizeof(mtx.data)); | 132 | memset(mtx.data, 0, sizeof(mtx.data)); |
| 133 | mtx.data[0] = 1; | 133 | mtx.data[0] = 1; |
| 134 | mtx.data[4] = c; | 134 | mtx.data[4] = c; |
| 135 | mtx.data[5] = -s; | 135 | mtx.data[5] = -s; |
| 136 | mtx.data[7] = s; | 136 | mtx.data[7] = s; |
| 137 | mtx.data[8] = c; | 137 | mtx.data[8] = c; |
| 138 | } | 138 | } |
| 139 | void Matrix33::RotateY(Matrix33 &mtx, float rad) | 139 | void Matrix33::RotateY(Matrix33 &mtx, float rad) |
| 140 | { | 140 | { |
| 141 | float s = sin(rad); | 141 | float s = sin(rad); |
| 142 | float c = cos(rad); | 142 | float c = cos(rad); |
| 143 | memset(mtx.data, 0, sizeof(mtx.data)); | 143 | memset(mtx.data, 0, sizeof(mtx.data)); |
| 144 | mtx.data[0] = c; | 144 | mtx.data[0] = c; |
| 145 | mtx.data[2] = s; | 145 | mtx.data[2] = s; |
| 146 | mtx.data[4] = 1; | 146 | mtx.data[4] = 1; |
| 147 | mtx.data[6] = -s; | 147 | mtx.data[6] = -s; |
| 148 | mtx.data[8] = c; | 148 | mtx.data[8] = c; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | void Matrix33::Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result) | 151 | void Matrix33::Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result) |
| 152 | { | 152 | { |
| 153 | MatrixMul(3, a.data, b.data, result.data); | 153 | MatrixMul(3, a.data, b.data, result.data); |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | void Matrix33::Multiply(const Matrix33 &a, const float vec[3], float result[3]) | 156 | void Matrix33::Multiply(const Matrix33 &a, const float vec[3], float result[3]) |
| 157 | { | 157 | { |
| 158 | for (int i = 0; i < 3; ++i) { | 158 | for (int i = 0; i < 3; ++i) { |
| 159 | result[i] = 0; | 159 | result[i] = 0; |
| 160 | for (int k = 0; k < 3; ++k) { | 160 | for (int k = 0; k < 3; ++k) { |
| 161 | result[i] += a.data[i * 3 + k] * vec[k]; | 161 | result[i] += a.data[i * 3 + k] * vec[k]; |
| 162 | } | 162 | } |
| 163 | } | 163 | } |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | void Matrix44::LoadIdentity(Matrix44 &mtx) | 166 | void Matrix44::LoadIdentity(Matrix44 &mtx) |
| 167 | { | 167 | { |
| 168 | memset(mtx.data, 0, sizeof(mtx.data)); | 168 | memset(mtx.data, 0, sizeof(mtx.data)); |
| 169 | mtx.data[0] = 1.0f; | 169 | mtx.data[0] = 1.0f; |
| 170 | mtx.data[5] = 1.0f; | 170 | mtx.data[5] = 1.0f; |
| 171 | mtx.data[10] = 1.0f; | 171 | mtx.data[10] = 1.0f; |
| 172 | mtx.data[15] = 1.0f; | 172 | mtx.data[15] = 1.0f; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | void Matrix44::LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33) | 175 | void Matrix44::LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33) |
| 176 | { | 176 | { |
| 177 | for (int i = 0; i < 3; ++i) | 177 | for (int i = 0; i < 3; ++i) |
| 178 | { | 178 | { |
| 179 | for (int j = 0; j < 3; ++j) | 179 | for (int j = 0; j < 3; ++j) |
| 180 | { | 180 | { |
| 181 | mtx.data[i * 4 + j] = m33.data[i * 3 + j]; | 181 | mtx.data[i * 4 + j] = m33.data[i * 3 + j]; |
| 182 | } | 182 | } |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | for (int i = 0; i < 3; ++i) | 185 | for (int i = 0; i < 3; ++i) |
| 186 | { | 186 | { |
| 187 | mtx.data[i * 4 + 3] = 0; | 187 | mtx.data[i * 4 + 3] = 0; |
| 188 | mtx.data[i + 12] = 0; | 188 | mtx.data[i + 12] = 0; |
| 189 | } | 189 | } |
| 190 | mtx.data[15] = 1.0f; | 190 | mtx.data[15] = 1.0f; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | void Matrix44::Set(Matrix44 &mtx, const float mtxArray[16]) | 193 | void Matrix44::Set(Matrix44 &mtx, const float mtxArray[16]) |
| 194 | { | 194 | { |
| 195 | for(int i = 0; i < 16; ++i) { | 195 | for(int i = 0; i < 16; ++i) { |
| 196 | mtx.data[i] = mtxArray[i]; | 196 | mtx.data[i] = mtxArray[i]; |
| 197 | } | 197 | } |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | void Matrix44::Translate(Matrix44 &mtx, const float vec[3]) | 200 | void Matrix44::Translate(Matrix44 &mtx, const float vec[3]) |
| 201 | { | 201 | { |
| 202 | LoadIdentity(mtx); | 202 | LoadIdentity(mtx); |
| 203 | mtx.data[3] = vec[0]; | 203 | mtx.data[3] = vec[0]; |
| 204 | mtx.data[7] = vec[1]; | 204 | mtx.data[7] = vec[1]; |
| 205 | mtx.data[11] = vec[2]; | 205 | mtx.data[11] = vec[2]; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | void Matrix44::Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result) | 208 | void Matrix44::Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result) |
| 209 | { | 209 | { |
| 210 | MatrixMul(4, a.data, b.data, result.data); | 210 | MatrixMul(4, a.data, b.data, result.data); |
| 211 | } | 211 | } |
| 212 | 212 | ||
diff --git a/src/common/src/math_util.h b/src/common/src/math_util.h index 4dd12c309..4410c5e01 100644 --- a/src/common/src/math_util.h +++ b/src/common/src/math_util.h | |||
| @@ -14,74 +14,74 @@ namespace MathUtil | |||
| 14 | { | 14 | { |
| 15 | 15 | ||
| 16 | static const u64 DOUBLE_SIGN = 0x8000000000000000ULL, | 16 | static const u64 DOUBLE_SIGN = 0x8000000000000000ULL, |
| 17 | DOUBLE_EXP = 0x7FF0000000000000ULL, | 17 | DOUBLE_EXP = 0x7FF0000000000000ULL, |
| 18 | DOUBLE_FRAC = 0x000FFFFFFFFFFFFFULL, | 18 | DOUBLE_FRAC = 0x000FFFFFFFFFFFFFULL, |
| 19 | DOUBLE_ZERO = 0x0000000000000000ULL; | 19 | DOUBLE_ZERO = 0x0000000000000000ULL; |
| 20 | 20 | ||
| 21 | static const u32 FLOAT_SIGN = 0x80000000, | 21 | static const u32 FLOAT_SIGN = 0x80000000, |
| 22 | FLOAT_EXP = 0x7F800000, | 22 | FLOAT_EXP = 0x7F800000, |
| 23 | FLOAT_FRAC = 0x007FFFFF, | 23 | FLOAT_FRAC = 0x007FFFFF, |
| 24 | FLOAT_ZERO = 0x00000000; | 24 | FLOAT_ZERO = 0x00000000; |
| 25 | 25 | ||
| 26 | union IntDouble { | 26 | union IntDouble { |
| 27 | double d; | 27 | double d; |
| 28 | u64 i; | 28 | u64 i; |
| 29 | }; | 29 | }; |
| 30 | union IntFloat { | 30 | union IntFloat { |
| 31 | float f; | 31 | float f; |
| 32 | u32 i; | 32 | u32 i; |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | inline bool IsNAN(double d) | 35 | inline bool IsNAN(double d) |
| 36 | { | 36 | { |
| 37 | IntDouble x; x.d = d; | 37 | IntDouble x; x.d = d; |
| 38 | return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | 38 | return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && |
| 39 | ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) ); | 39 | ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) ); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | inline bool IsQNAN(double d) | 42 | inline bool IsQNAN(double d) |
| 43 | { | 43 | { |
| 44 | IntDouble x; x.d = d; | 44 | IntDouble x; x.d = d; |
| 45 | return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | 45 | return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && |
| 46 | ((x.i & 0x0007fffffffffffULL) == 0x000000000000000ULL) && | 46 | ((x.i & 0x0007fffffffffffULL) == 0x000000000000000ULL) && |
| 47 | ((x.i & 0x000800000000000ULL) == 0x000800000000000ULL) ); | 47 | ((x.i & 0x000800000000000ULL) == 0x000800000000000ULL) ); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | inline bool IsSNAN(double d) | 50 | inline bool IsSNAN(double d) |
| 51 | { | 51 | { |
| 52 | IntDouble x; x.d = d; | 52 | IntDouble x; x.d = d; |
| 53 | return( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && | 53 | return( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && |
| 54 | ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) && | 54 | ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) && |
| 55 | ((x.i & 0x0008000000000000ULL) == DOUBLE_ZERO) ); | 55 | ((x.i & 0x0008000000000000ULL) == DOUBLE_ZERO) ); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | inline float FlushToZero(float f) | 58 | inline float FlushToZero(float f) |
| 59 | { | 59 | { |
| 60 | IntFloat x; x.f = f; | 60 | IntFloat x; x.f = f; |
| 61 | if ((x.i & FLOAT_EXP) == 0) | 61 | if ((x.i & FLOAT_EXP) == 0) |
| 62 | x.i &= FLOAT_SIGN; // turn into signed zero | 62 | x.i &= FLOAT_SIGN; // turn into signed zero |
| 63 | return x.f; | 63 | return x.f; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | inline double FlushToZeroAsFloat(double d) | 66 | inline double FlushToZeroAsFloat(double d) |
| 67 | { | 67 | { |
| 68 | IntDouble x; x.d = d; | 68 | IntDouble x; x.d = d; |
| 69 | if ((x.i & DOUBLE_EXP) < 0x3800000000000000ULL) | 69 | if ((x.i & DOUBLE_EXP) < 0x3800000000000000ULL) |
| 70 | x.i &= DOUBLE_SIGN; // turn into signed zero | 70 | x.i &= DOUBLE_SIGN; // turn into signed zero |
| 71 | return x.d; | 71 | return x.d; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | enum PPCFpClass | 74 | enum PPCFpClass |
| 75 | { | 75 | { |
| 76 | PPC_FPCLASS_QNAN = 0x11, | 76 | PPC_FPCLASS_QNAN = 0x11, |
| 77 | PPC_FPCLASS_NINF = 0x9, | 77 | PPC_FPCLASS_NINF = 0x9, |
| 78 | PPC_FPCLASS_NN = 0x8, | 78 | PPC_FPCLASS_NN = 0x8, |
| 79 | PPC_FPCLASS_ND = 0x18, | 79 | PPC_FPCLASS_ND = 0x18, |
| 80 | PPC_FPCLASS_NZ = 0x12, | 80 | PPC_FPCLASS_NZ = 0x12, |
| 81 | PPC_FPCLASS_PZ = 0x2, | 81 | PPC_FPCLASS_PZ = 0x2, |
| 82 | PPC_FPCLASS_PD = 0x14, | 82 | PPC_FPCLASS_PD = 0x14, |
| 83 | PPC_FPCLASS_PN = 0x4, | 83 | PPC_FPCLASS_PN = 0x4, |
| 84 | PPC_FPCLASS_PINF = 0x5, | 84 | PPC_FPCLASS_PINF = 0x5, |
| 85 | }; | 85 | }; |
| 86 | 86 | ||
| 87 | // Uses PowerPC conventions for the return value, so it can be easily | 87 | // Uses PowerPC conventions for the return value, so it can be easily |
| @@ -93,42 +93,42 @@ u32 ClassifyFloat(float fvalue); | |||
| 93 | template<class T> | 93 | template<class T> |
| 94 | struct Rectangle | 94 | struct Rectangle |
| 95 | { | 95 | { |
| 96 | T left; | 96 | T left; |
| 97 | T top; | 97 | T top; |
| 98 | T right; | 98 | T right; |
| 99 | T bottom; | 99 | T bottom; |
| 100 | 100 | ||
| 101 | Rectangle() | 101 | Rectangle() |
| 102 | { } | 102 | { } |
| 103 | 103 | ||
| 104 | Rectangle(T theLeft, T theTop, T theRight, T theBottom) | 104 | Rectangle(T theLeft, T theTop, T theRight, T theBottom) |
| 105 | : left(theLeft), top(theTop), right(theRight), bottom(theBottom) | 105 | : left(theLeft), top(theTop), right(theRight), bottom(theBottom) |
| 106 | { } | 106 | { } |
| 107 | 107 | ||
| 108 | bool operator==(const Rectangle& r) { return left==r.left && top==r.top && right==r.right && bottom==r.bottom; } | 108 | bool operator==(const Rectangle& r) { return left==r.left && top==r.top && right==r.right && bottom==r.bottom; } |
| 109 | 109 | ||
| 110 | T GetWidth() const { return abs(right - left); } | 110 | T GetWidth() const { return abs(right - left); } |
| 111 | T GetHeight() const { return abs(bottom - top); } | 111 | T GetHeight() const { return abs(bottom - top); } |
| 112 | 112 | ||
| 113 | // If the rectangle is in a coordinate system with a lower-left origin, use | 113 | // If the rectangle is in a coordinate system with a lower-left origin, use |
| 114 | // this Clamp. | 114 | // this Clamp. |
| 115 | void ClampLL(T x1, T y1, T x2, T y2) | 115 | void ClampLL(T x1, T y1, T x2, T y2) |
| 116 | { | 116 | { |
| 117 | if (left < x1) left = x1; | 117 | if (left < x1) left = x1; |
| 118 | if (right > x2) right = x2; | 118 | if (right > x2) right = x2; |
| 119 | if (top > y1) top = y1; | 119 | if (top > y1) top = y1; |
| 120 | if (bottom < y2) bottom = y2; | 120 | if (bottom < y2) bottom = y2; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | // If the rectangle is in a coordinate system with an upper-left origin, | 123 | // If the rectangle is in a coordinate system with an upper-left origin, |
| 124 | // use this Clamp. | 124 | // use this Clamp. |
| 125 | void ClampUL(T x1, T y1, T x2, T y2) | 125 | void ClampUL(T x1, T y1, T x2, T y2) |
| 126 | { | 126 | { |
| 127 | if (left < x1) left = x1; | 127 | if (left < x1) left = x1; |
| 128 | if (right > x2) right = x2; | 128 | if (right > x2) right = x2; |
| 129 | if (top < y1) top = y1; | 129 | if (top < y1) top = y1; |
| 130 | if (bottom > y2) bottom = y2; | 130 | if (bottom > y2) bottom = y2; |
| 131 | } | 131 | } |
| 132 | }; | 132 | }; |
| 133 | 133 | ||
| 134 | } // namespace MathUtil | 134 | } // namespace MathUtil |
| @@ -138,28 +138,28 @@ inline double pow2(double x) {return x * x;} | |||
| 138 | 138 | ||
| 139 | float MathFloatVectorSum(const std::vector<float>&); | 139 | float MathFloatVectorSum(const std::vector<float>&); |
| 140 | 140 | ||
| 141 | #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) | 141 | #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) |
| 142 | #define ROUND_DOWN(x, a) ((x) & ~((a) - 1)) | 142 | #define ROUND_DOWN(x, a) ((x) & ~((a) - 1)) |
| 143 | 143 | ||
| 144 | // Rounds down. 0 -> undefined | 144 | // Rounds down. 0 -> undefined |
| 145 | inline u64 Log2(u64 val) | 145 | inline u64 Log2(u64 val) |
| 146 | { | 146 | { |
| 147 | #if defined(__GNUC__) | 147 | #if defined(__GNUC__) |
| 148 | return 63 - __builtin_clzll(val); | 148 | return 63 - __builtin_clzll(val); |
| 149 | 149 | ||
| 150 | #elif defined(_MSC_VER) && defined(_M_X64) | 150 | #elif defined(_MSC_VER) && defined(_M_X64) |
| 151 | unsigned long result = -1; | 151 | unsigned long result = -1; |
| 152 | _BitScanReverse64(&result, val); | 152 | _BitScanReverse64(&result, val); |
| 153 | return result; | 153 | return result; |
| 154 | 154 | ||
| 155 | #else | 155 | #else |
| 156 | u64 result = -1; | 156 | u64 result = -1; |
| 157 | while (val != 0) | 157 | while (val != 0) |
| 158 | { | 158 | { |
| 159 | val >>= 1; | 159 | val >>= 1; |
| 160 | ++result; | 160 | ++result; |
| 161 | } | 161 | } |
| 162 | return result; | 162 | return result; |
| 163 | #endif | 163 | #endif |
| 164 | } | 164 | } |
| 165 | 165 | ||
| @@ -169,32 +169,32 @@ inline u64 Log2(u64 val) | |||
| 169 | class Matrix33 | 169 | class Matrix33 |
| 170 | { | 170 | { |
| 171 | public: | 171 | public: |
| 172 | static void LoadIdentity(Matrix33 &mtx); | 172 | static void LoadIdentity(Matrix33 &mtx); |
| 173 | 173 | ||
| 174 | // set mtx to be a rotation matrix around the x axis | 174 | // set mtx to be a rotation matrix around the x axis |
| 175 | static void RotateX(Matrix33 &mtx, float rad); | 175 | static void RotateX(Matrix33 &mtx, float rad); |
| 176 | // set mtx to be a rotation matrix around the y axis | 176 | // set mtx to be a rotation matrix around the y axis |
| 177 | static void RotateY(Matrix33 &mtx, float rad); | 177 | static void RotateY(Matrix33 &mtx, float rad); |
| 178 | 178 | ||
| 179 | // set result = a x b | 179 | // set result = a x b |
| 180 | static void Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result); | 180 | static void Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result); |
| 181 | static void Multiply(const Matrix33 &a, const float vec[3], float result[3]); | 181 | static void Multiply(const Matrix33 &a, const float vec[3], float result[3]); |
| 182 | 182 | ||
| 183 | float data[9]; | 183 | float data[9]; |
| 184 | }; | 184 | }; |
| 185 | 185 | ||
| 186 | class Matrix44 | 186 | class Matrix44 |
| 187 | { | 187 | { |
| 188 | public: | 188 | public: |
| 189 | static void LoadIdentity(Matrix44 &mtx); | 189 | static void LoadIdentity(Matrix44 &mtx); |
| 190 | static void LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33); | 190 | static void LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33); |
| 191 | static void Set(Matrix44 &mtx, const float mtxArray[16]); | 191 | static void Set(Matrix44 &mtx, const float mtxArray[16]); |
| 192 | 192 | ||
| 193 | static void Translate(Matrix44 &mtx, const float vec[3]); | 193 | static void Translate(Matrix44 &mtx, const float vec[3]); |
| 194 | 194 | ||
| 195 | static void Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result); | 195 | static void Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result); |
| 196 | 196 | ||
| 197 | float data[16]; | 197 | float data[16]; |
| 198 | }; | 198 | }; |
| 199 | 199 | ||
| 200 | #endif // _MATH_UTIL_H_ | 200 | #endif // _MATH_UTIL_H_ |
diff --git a/src/common/src/memory_util.cpp b/src/common/src/memory_util.cpp index 346d2e525..cc6e77b35 100644 --- a/src/common/src/memory_util.cpp +++ b/src/common/src/memory_util.cpp | |||
| @@ -27,148 +27,148 @@ | |||
| 27 | void* AllocateExecutableMemory(size_t size, bool low) | 27 | void* AllocateExecutableMemory(size_t size, bool low) |
| 28 | { | 28 | { |
| 29 | #if defined(_WIN32) | 29 | #if defined(_WIN32) |
| 30 | void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); | 30 | void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); |
| 31 | #else | 31 | #else |
| 32 | static char *map_hint = 0; | 32 | static char *map_hint = 0; |
| 33 | #if defined(__x86_64__) && !defined(MAP_32BIT) | 33 | #if defined(__x86_64__) && !defined(MAP_32BIT) |
| 34 | // This OS has no flag to enforce allocation below the 4 GB boundary, | 34 | // This OS has no flag to enforce allocation below the 4 GB boundary, |
| 35 | // but if we hint that we want a low address it is very likely we will | 35 | // but if we hint that we want a low address it is very likely we will |
| 36 | // get one. | 36 | // get one. |
| 37 | // An older version of this code used MAP_FIXED, but that has the side | 37 | // An older version of this code used MAP_FIXED, but that has the side |
| 38 | // effect of discarding already mapped pages that happen to be in the | 38 | // effect of discarding already mapped pages that happen to be in the |
| 39 | // requested virtual memory range (such as the emulated RAM, sometimes). | 39 | // requested virtual memory range (such as the emulated RAM, sometimes). |
| 40 | if (low && (!map_hint)) | 40 | if (low && (!map_hint)) |
| 41 | map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */ | 41 | map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */ |
| 42 | #endif | 42 | #endif |
| 43 | void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, | 43 | void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, |
| 44 | MAP_ANON | MAP_PRIVATE | 44 | MAP_ANON | MAP_PRIVATE |
| 45 | #if defined(__x86_64__) && defined(MAP_32BIT) | 45 | #if defined(__x86_64__) && defined(MAP_32BIT) |
| 46 | | (low ? MAP_32BIT : 0) | 46 | | (low ? MAP_32BIT : 0) |
| 47 | #endif | 47 | #endif |
| 48 | , -1, 0); | 48 | , -1, 0); |
| 49 | #endif /* defined(_WIN32) */ | 49 | #endif /* defined(_WIN32) */ |
| 50 | 50 | ||
| 51 | // printf("Mapped executable memory at %p (size %ld)\n", ptr, | 51 | // printf("Mapped executable memory at %p (size %ld)\n", ptr, |
| 52 | // (unsigned long)size); | 52 | // (unsigned long)size); |
| 53 | 53 | ||
| 54 | #if defined(__FreeBSD__) | 54 | #if defined(__FreeBSD__) |
| 55 | if (ptr == MAP_FAILED) | 55 | if (ptr == MAP_FAILED) |
| 56 | { | 56 | { |
| 57 | ptr = NULL; | 57 | ptr = NULL; |
| 58 | #else | 58 | #else |
| 59 | if (ptr == NULL) | 59 | if (ptr == NULL) |
| 60 | { | 60 | { |
| 61 | #endif | 61 | #endif |
| 62 | PanicAlert("Failed to allocate executable memory"); | 62 | PanicAlert("Failed to allocate executable memory"); |
| 63 | } | 63 | } |
| 64 | #if !defined(_WIN32) && defined(__x86_64__) && !defined(MAP_32BIT) | 64 | #if !defined(_WIN32) && defined(__x86_64__) && !defined(MAP_32BIT) |
| 65 | else | 65 | else |
| 66 | { | 66 | { |
| 67 | if (low) | 67 | if (low) |
| 68 | { | 68 | { |
| 69 | map_hint += size; | 69 | map_hint += size; |
| 70 | map_hint = (char*)round_page(map_hint); /* round up to the next page */ | 70 | map_hint = (char*)round_page(map_hint); /* round up to the next page */ |
| 71 | // printf("Next map will (hopefully) be at %p\n", map_hint); | 71 | // printf("Next map will (hopefully) be at %p\n", map_hint); |
| 72 | } | 72 | } |
| 73 | } | 73 | } |
| 74 | #endif | 74 | #endif |
| 75 | 75 | ||
| 76 | #if defined(_M_X64) | 76 | #if defined(_M_X64) |
| 77 | if ((u64)ptr >= 0x80000000 && low == true) | 77 | if ((u64)ptr >= 0x80000000 && low == true) |
| 78 | PanicAlert("Executable memory ended up above 2GB!"); | 78 | PanicAlert("Executable memory ended up above 2GB!"); |
| 79 | #endif | 79 | #endif |
| 80 | 80 | ||
| 81 | return ptr; | 81 | return ptr; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | void* AllocateMemoryPages(size_t size) | 84 | void* AllocateMemoryPages(size_t size) |
| 85 | { | 85 | { |
| 86 | #ifdef _WIN32 | 86 | #ifdef _WIN32 |
| 87 | void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); | 87 | void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); |
| 88 | #else | 88 | #else |
| 89 | void* ptr = mmap(0, size, PROT_READ | PROT_WRITE, | 89 | void* ptr = mmap(0, size, PROT_READ | PROT_WRITE, |
| 90 | MAP_ANON | MAP_PRIVATE, -1, 0); | 90 | MAP_ANON | MAP_PRIVATE, -1, 0); |
| 91 | #endif | 91 | #endif |
| 92 | 92 | ||
| 93 | // printf("Mapped memory at %p (size %ld)\n", ptr, | 93 | // printf("Mapped memory at %p (size %ld)\n", ptr, |
| 94 | // (unsigned long)size); | 94 | // (unsigned long)size); |
| 95 | 95 | ||
| 96 | if (ptr == NULL) | 96 | if (ptr == NULL) |
| 97 | PanicAlert("Failed to allocate raw memory"); | 97 | PanicAlert("Failed to allocate raw memory"); |
| 98 | 98 | ||
| 99 | return ptr; | 99 | return ptr; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | void* AllocateAlignedMemory(size_t size,size_t alignment) | 102 | void* AllocateAlignedMemory(size_t size,size_t alignment) |
| 103 | { | 103 | { |
| 104 | #ifdef _WIN32 | 104 | #ifdef _WIN32 |
| 105 | void* ptr = _aligned_malloc(size,alignment); | 105 | void* ptr = _aligned_malloc(size,alignment); |
| 106 | #else | 106 | #else |
| 107 | void* ptr = NULL; | 107 | void* ptr = NULL; |
| 108 | #ifdef ANDROID | 108 | #ifdef ANDROID |
| 109 | ptr = memalign(alignment, size); | 109 | ptr = memalign(alignment, size); |
| 110 | #else | 110 | #else |
| 111 | if (posix_memalign(&ptr, alignment, size) != 0) | 111 | if (posix_memalign(&ptr, alignment, size) != 0) |
| 112 | ERROR_LOG(MEMMAP, "Failed to allocate aligned memory"); | 112 | ERROR_LOG(MEMMAP, "Failed to allocate aligned memory"); |
| 113 | #endif | 113 | #endif |
| 114 | #endif | 114 | #endif |
| 115 | 115 | ||
| 116 | // printf("Mapped memory at %p (size %ld)\n", ptr, | 116 | // printf("Mapped memory at %p (size %ld)\n", ptr, |
| 117 | // (unsigned long)size); | 117 | // (unsigned long)size); |
| 118 | 118 | ||
| 119 | if (ptr == NULL) | 119 | if (ptr == NULL) |
| 120 | PanicAlert("Failed to allocate aligned memory"); | 120 | PanicAlert("Failed to allocate aligned memory"); |
| 121 | 121 | ||
| 122 | return ptr; | 122 | return ptr; |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | void FreeMemoryPages(void* ptr, size_t size) | 125 | void FreeMemoryPages(void* ptr, size_t size) |
| 126 | { | 126 | { |
| 127 | if (ptr) | 127 | if (ptr) |
| 128 | { | 128 | { |
| 129 | #ifdef _WIN32 | 129 | #ifdef _WIN32 |
| 130 | 130 | ||
| 131 | if (!VirtualFree(ptr, 0, MEM_RELEASE)) | 131 | if (!VirtualFree(ptr, 0, MEM_RELEASE)) |
| 132 | PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg()); | 132 | PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg()); |
| 133 | ptr = NULL; // Is this our responsibility? | 133 | ptr = NULL; // Is this our responsibility? |
| 134 | 134 | ||
| 135 | #else | 135 | #else |
| 136 | munmap(ptr, size); | 136 | munmap(ptr, size); |
| 137 | #endif | 137 | #endif |
| 138 | } | 138 | } |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | void FreeAlignedMemory(void* ptr) | 141 | void FreeAlignedMemory(void* ptr) |
| 142 | { | 142 | { |
| 143 | if (ptr) | 143 | if (ptr) |
| 144 | { | 144 | { |
| 145 | #ifdef _WIN32 | 145 | #ifdef _WIN32 |
| 146 | _aligned_free(ptr); | 146 | _aligned_free(ptr); |
| 147 | #else | 147 | #else |
| 148 | free(ptr); | 148 | free(ptr); |
| 149 | #endif | 149 | #endif |
| 150 | } | 150 | } |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) | 153 | void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) |
| 154 | { | 154 | { |
| 155 | #ifdef _WIN32 | 155 | #ifdef _WIN32 |
| 156 | DWORD oldValue; | 156 | DWORD oldValue; |
| 157 | if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue)) | 157 | if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue)) |
| 158 | PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg()); | 158 | PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg()); |
| 159 | #else | 159 | #else |
| 160 | mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ); | 160 | mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ); |
| 161 | #endif | 161 | #endif |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) | 164 | void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) |
| 165 | { | 165 | { |
| 166 | #ifdef _WIN32 | 166 | #ifdef _WIN32 |
| 167 | DWORD oldValue; | 167 | DWORD oldValue; |
| 168 | if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue)) | 168 | if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue)) |
| 169 | PanicAlert("UnWriteProtectMemory failed!\n%s", GetLastErrorMsg()); | 169 | PanicAlert("UnWriteProtectMemory failed!\n%s", GetLastErrorMsg()); |
| 170 | #else | 170 | #else |
| 171 | mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ); | 171 | mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ); |
| 172 | #endif | 172 | #endif |
| 173 | } | 173 | } |
| 174 | 174 | ||
| @@ -176,22 +176,22 @@ std::string MemUsage() | |||
| 176 | { | 176 | { |
| 177 | #ifdef _WIN32 | 177 | #ifdef _WIN32 |
| 178 | #pragma comment(lib, "psapi") | 178 | #pragma comment(lib, "psapi") |
| 179 | DWORD processID = GetCurrentProcessId(); | 179 | DWORD processID = GetCurrentProcessId(); |
| 180 | HANDLE hProcess; | 180 | HANDLE hProcess; |
| 181 | PROCESS_MEMORY_COUNTERS pmc; | 181 | PROCESS_MEMORY_COUNTERS pmc; |
| 182 | std::string Ret; | 182 | std::string Ret; |
| 183 | 183 | ||
| 184 | // Print information about the memory usage of the process. | 184 | // Print information about the memory usage of the process. |
| 185 | 185 | ||
| 186 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); | 186 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); |
| 187 | if (NULL == hProcess) return "MemUsage Error"; | 187 | if (NULL == hProcess) return "MemUsage Error"; |
| 188 | 188 | ||
| 189 | if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) | 189 | if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) |
| 190 | Ret = StringFromFormat("%s K", ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); | 190 | Ret = StringFromFormat("%s K", ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); |
| 191 | 191 | ||
| 192 | CloseHandle(hProcess); | 192 | CloseHandle(hProcess); |
| 193 | return Ret; | 193 | return Ret; |
| 194 | #else | 194 | #else |
| 195 | return ""; | 195 | return ""; |
| 196 | #endif | 196 | #endif |
| 197 | } | 197 | } |
diff --git a/src/common/src/misc.cpp b/src/common/src/misc.cpp index 5b9e38ffb..935805478 100644 --- a/src/common/src/misc.cpp +++ b/src/common/src/misc.cpp | |||
| @@ -18,20 +18,20 @@ | |||
| 18 | // This function might change the error code. | 18 | // This function might change the error code. |
| 19 | const char* GetLastErrorMsg() | 19 | const char* GetLastErrorMsg() |
| 20 | { | 20 | { |
| 21 | static const size_t buff_size = 255; | 21 | static const size_t buff_size = 255; |
| 22 | 22 | ||
| 23 | #ifdef _WIN32 | 23 | #ifdef _WIN32 |
| 24 | static __declspec(thread) char err_str[buff_size] = {}; | 24 | static __declspec(thread) char err_str[buff_size] = {}; |
| 25 | 25 | ||
| 26 | FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), | 26 | FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), |
| 27 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | 27 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
| 28 | err_str, buff_size, NULL); | 28 | err_str, buff_size, NULL); |
| 29 | #else | 29 | #else |
| 30 | static __thread char err_str[buff_size] = {}; | 30 | static __thread char err_str[buff_size] = {}; |
| 31 | 31 | ||
| 32 | // Thread safe (XSI-compliant) | 32 | // Thread safe (XSI-compliant) |
| 33 | strerror_r(errno, err_str, buff_size); | 33 | strerror_r(errno, err_str, buff_size); |
| 34 | #endif | 34 | #endif |
| 35 | 35 | ||
| 36 | return err_str; | 36 | return err_str; |
| 37 | } | 37 | } |
diff --git a/src/common/src/msg_handler.cpp b/src/common/src/msg_handler.cpp index 62cbe0aa7..8e9fe218e 100644 --- a/src/common/src/msg_handler.cpp +++ b/src/common/src/msg_handler.cpp | |||
| @@ -18,90 +18,90 @@ static StringTranslator str_translator = DefaultStringTranslator; | |||
| 18 | // wxWidgets is enabled we will use wxMsgAlert() that is defined in Main.cpp | 18 | // wxWidgets is enabled we will use wxMsgAlert() that is defined in Main.cpp |
| 19 | void RegisterMsgAlertHandler(MsgAlertHandler handler) | 19 | void RegisterMsgAlertHandler(MsgAlertHandler handler) |
| 20 | { | 20 | { |
| 21 | msg_handler = handler; | 21 | msg_handler = handler; |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | // Select translation function. For wxWidgets use wxStringTranslator in Main.cpp | 24 | // Select translation function. For wxWidgets use wxStringTranslator in Main.cpp |
| 25 | void RegisterStringTranslator(StringTranslator translator) | 25 | void RegisterStringTranslator(StringTranslator translator) |
| 26 | { | 26 | { |
| 27 | str_translator = translator; | 27 | str_translator = translator; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | // enable/disable the alert handler | 30 | // enable/disable the alert handler |
| 31 | void SetEnableAlert(bool enable) | 31 | void SetEnableAlert(bool enable) |
| 32 | { | 32 | { |
| 33 | AlertEnabled = enable; | 33 | AlertEnabled = enable; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | // This is the first stop for gui alerts where the log is updated and the | 36 | // This is the first stop for gui alerts where the log is updated and the |
| 37 | // correct window is shown | 37 | // correct window is shown |
| 38 | bool MsgAlert(bool yes_no, int Style, const char* format, ...) | 38 | bool MsgAlert(bool yes_no, int Style, const char* format, ...) |
| 39 | { | 39 | { |
| 40 | // Read message and write it to the log | 40 | // Read message and write it to the log |
| 41 | std::string caption; | 41 | std::string caption; |
| 42 | char buffer[2048]; | 42 | char buffer[2048]; |
| 43 | 43 | ||
| 44 | static std::string info_caption; | 44 | static std::string info_caption; |
| 45 | static std::string warn_caption; | 45 | static std::string warn_caption; |
| 46 | static std::string ques_caption; | 46 | static std::string ques_caption; |
| 47 | static std::string crit_caption; | 47 | static std::string crit_caption; |
| 48 | 48 | ||
| 49 | if (!info_caption.length()) | 49 | if (!info_caption.length()) |
| 50 | { | 50 | { |
| 51 | info_caption = str_translator(_trans("Information")); | 51 | info_caption = str_translator(_trans("Information")); |
| 52 | ques_caption = str_translator(_trans("Question")); | 52 | ques_caption = str_translator(_trans("Question")); |
| 53 | warn_caption = str_translator(_trans("Warning")); | 53 | warn_caption = str_translator(_trans("Warning")); |
| 54 | crit_caption = str_translator(_trans("Critical")); | 54 | crit_caption = str_translator(_trans("Critical")); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | switch(Style) | 57 | switch(Style) |
| 58 | { | 58 | { |
| 59 | case INFORMATION: | 59 | case INFORMATION: |
| 60 | caption = info_caption; | 60 | caption = info_caption; |
| 61 | break; | 61 | break; |
| 62 | case QUESTION: | 62 | case QUESTION: |
| 63 | caption = ques_caption; | 63 | caption = ques_caption; |
| 64 | break; | 64 | break; |
| 65 | case WARNING: | 65 | case WARNING: |
| 66 | caption = warn_caption; | 66 | caption = warn_caption; |
| 67 | break; | 67 | break; |
| 68 | case CRITICAL: | 68 | case CRITICAL: |
| 69 | caption = crit_caption; | 69 | caption = crit_caption; |
| 70 | break; | 70 | break; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | va_list args; | 73 | va_list args; |
| 74 | va_start(args, format); | 74 | va_start(args, format); |
| 75 | CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args); | 75 | CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args); |
| 76 | va_end(args); | 76 | va_end(args); |
| 77 | 77 | ||
| 78 | ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer); | 78 | ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer); |
| 79 | 79 | ||
| 80 | // Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored | 80 | // Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored |
| 81 | if (msg_handler && (AlertEnabled || Style == QUESTION || Style == CRITICAL)) | 81 | if (msg_handler && (AlertEnabled || Style == QUESTION || Style == CRITICAL)) |
| 82 | return msg_handler(caption.c_str(), buffer, yes_no, Style); | 82 | return msg_handler(caption.c_str(), buffer, yes_no, Style); |
| 83 | 83 | ||
| 84 | return true; | 84 | return true; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | // Default non library dependent panic alert | 87 | // Default non library dependent panic alert |
| 88 | bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style) | 88 | bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style) |
| 89 | { | 89 | { |
| 90 | //#ifdef _WIN32 | 90 | //#ifdef _WIN32 |
| 91 | // int STYLE = MB_ICONINFORMATION; | 91 | // int STYLE = MB_ICONINFORMATION; |
| 92 | // if (Style == QUESTION) STYLE = MB_ICONQUESTION; | 92 | // if (Style == QUESTION) STYLE = MB_ICONQUESTION; |
| 93 | // if (Style == WARNING) STYLE = MB_ICONWARNING; | 93 | // if (Style == WARNING) STYLE = MB_ICONWARNING; |
| 94 | // | 94 | // |
| 95 | // return IDYES == MessageBox(0, UTF8ToTStr(text).c_str(), UTF8ToTStr(caption).c_str(), STYLE | (yes_no ? MB_YESNO : MB_OK)); | 95 | // return IDYES == MessageBox(0, UTF8ToTStr(text).c_str(), UTF8ToTStr(caption).c_str(), STYLE | (yes_no ? MB_YESNO : MB_OK)); |
| 96 | //#else | 96 | //#else |
| 97 | printf("%s\n", text); | 97 | printf("%s\n", text); |
| 98 | return true; | 98 | return true; |
| 99 | //#endif | 99 | //#endif |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | // Default (non) translator | 102 | // Default (non) translator |
| 103 | std::string DefaultStringTranslator(const char* text) | 103 | std::string DefaultStringTranslator(const char* text) |
| 104 | { | 104 | { |
| 105 | return text; | 105 | return text; |
| 106 | } | 106 | } |
| 107 | 107 | ||
diff --git a/src/common/src/msg_handler.h b/src/common/src/msg_handler.h index 7de10c7b0..bde2808fa 100644 --- a/src/common/src/msg_handler.h +++ b/src/common/src/msg_handler.h | |||
| @@ -10,10 +10,10 @@ | |||
| 10 | // Message alerts | 10 | // Message alerts |
| 11 | enum MSG_TYPE | 11 | enum MSG_TYPE |
| 12 | { | 12 | { |
| 13 | INFORMATION, | 13 | INFORMATION, |
| 14 | QUESTION, | 14 | QUESTION, |
| 15 | WARNING, | 15 | WARNING, |
| 16 | CRITICAL | 16 | CRITICAL |
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | typedef bool (*MsgAlertHandler)(const char* caption, const char* text, | 19 | typedef bool (*MsgAlertHandler)(const char* caption, const char* text, |
| @@ -25,49 +25,49 @@ void RegisterStringTranslator(StringTranslator translator); | |||
| 25 | 25 | ||
| 26 | extern bool MsgAlert(bool yes_no, int Style, const char* format, ...) | 26 | extern bool MsgAlert(bool yes_no, int Style, const char* format, ...) |
| 27 | #ifdef __GNUC__ | 27 | #ifdef __GNUC__ |
| 28 | __attribute__((format(printf, 3, 4))) | 28 | __attribute__((format(printf, 3, 4))) |
| 29 | #endif | 29 | #endif |
| 30 | ; | 30 | ; |
| 31 | void SetEnableAlert(bool enable); | 31 | void SetEnableAlert(bool enable); |
| 32 | 32 | ||
| 33 | #ifndef GEKKO | 33 | #ifndef GEKKO |
| 34 | #ifdef _WIN32 | 34 | #ifdef _WIN32 |
| 35 | #define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__) | 35 | #define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__) |
| 36 | #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__) | 36 | #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__) |
| 37 | #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__) | 37 | #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__) |
| 38 | #define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__) | 38 | #define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__) |
| 39 | #define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__) | 39 | #define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__) |
| 40 | // Use these macros (that do the same thing) if the message should be translated. | 40 | // Use these macros (that do the same thing) if the message should be translated. |
| 41 | #define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__) | 41 | #define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__) |
| 42 | #define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__) | 42 | #define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__) |
| 43 | #define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__) | 43 | #define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__) |
| 44 | #define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__) | 44 | #define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, __VA_ARGS__) |
| 45 | #define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__) | 45 | #define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, __VA_ARGS__) |
| 46 | #else | 46 | #else |
| 47 | #define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__) | 47 | #define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__) |
| 48 | #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__) | 48 | #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__) |
| 49 | #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__) | 49 | #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__) |
| 50 | #define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__) | 50 | #define AskYesNo(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__) |
| 51 | #define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__) | 51 | #define CriticalAlert(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__) |
| 52 | // Use these macros (that do the same thing) if the message should be translated. | 52 | // Use these macros (that do the same thing) if the message should be translated. |
| 53 | #define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__) | 53 | #define SuccessAlertT(format, ...) MsgAlert(false, INFORMATION, format, ##__VA_ARGS__) |
| 54 | #define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__) | 54 | #define PanicAlertT(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__) |
| 55 | #define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__) | 55 | #define PanicYesNoT(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__) |
| 56 | #define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__) | 56 | #define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__) |
| 57 | #define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__) | 57 | #define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__) |
| 58 | #endif | 58 | #endif |
| 59 | #else | 59 | #else |
| 60 | // GEKKO | 60 | // GEKKO |
| 61 | #define SuccessAlert(format, ...) ; | 61 | #define SuccessAlert(format, ...) ; |
| 62 | #define PanicAlert(format, ...) ; | 62 | #define PanicAlert(format, ...) ; |
| 63 | #define PanicYesNo(format, ...) ; | 63 | #define PanicYesNo(format, ...) ; |
| 64 | #define AskYesNo(format, ...) ; | 64 | #define AskYesNo(format, ...) ; |
| 65 | #define CriticalAlert(format, ...) ; | 65 | #define CriticalAlert(format, ...) ; |
| 66 | #define SuccessAlertT(format, ...) ; | 66 | #define SuccessAlertT(format, ...) ; |
| 67 | #define PanicAlertT(format, ...) ; | 67 | #define PanicAlertT(format, ...) ; |
| 68 | #define PanicYesNoT(format, ...) ; | 68 | #define PanicYesNoT(format, ...) ; |
| 69 | #define AskYesNoT(format, ...) ; | 69 | #define AskYesNoT(format, ...) ; |
| 70 | #define CriticalAlertT(format, ...) ; | 70 | #define CriticalAlertT(format, ...) ; |
| 71 | #endif | 71 | #endif |
| 72 | 72 | ||
| 73 | #endif // _MSGHANDLER_H_ | 73 | #endif // _MSGHANDLER_H_ |
diff --git a/src/common/src/platform.h b/src/common/src/platform.h index d8eacaa84..84c6b6365 100644 --- a/src/common/src/platform.h +++ b/src/common/src/platform.h | |||
| @@ -76,9 +76,9 @@ | |||
| 76 | #define EMU_FASTCALL __fastcall | 76 | #define EMU_FASTCALL __fastcall |
| 77 | 77 | ||
| 78 | inline struct tm* localtime_r(const time_t *clock, struct tm *result) { | 78 | inline struct tm* localtime_r(const time_t *clock, struct tm *result) { |
| 79 | if (localtime_s(result, clock) == 0) | 79 | if (localtime_s(result, clock) == 0) |
| 80 | return result; | 80 | return result; |
| 81 | return NULL; | 81 | return NULL; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | #else | 84 | #else |
diff --git a/src/common/src/std_condition_variable.h b/src/common/src/std_condition_variable.h index d44545e61..cee7a9dcd 100644 --- a/src/common/src/std_condition_variable.h +++ b/src/common/src/std_condition_variable.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | #ifndef CONDITION_VARIABLE_H_ | 2 | #ifndef CONDITION_VARIABLE_H_ |
| 3 | #define CONDITION_VARIABLE_H_ | 3 | #define CONDITION_VARIABLE_H_ |
| 4 | 4 | ||
| 5 | #define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z)) | 5 | #define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z)) |
| 6 | #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) | 6 | #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) |
| 7 | 7 | ||
| 8 | #ifndef __has_include | 8 | #ifndef __has_include |
| @@ -47,121 +47,121 @@ namespace std | |||
| 47 | class condition_variable | 47 | class condition_variable |
| 48 | { | 48 | { |
| 49 | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | 49 | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) |
| 50 | typedef CONDITION_VARIABLE native_type; | 50 | typedef CONDITION_VARIABLE native_type; |
| 51 | #elif defined(_WIN32) | 51 | #elif defined(_WIN32) |
| 52 | typedef HANDLE native_type; | 52 | typedef HANDLE native_type; |
| 53 | #else | 53 | #else |
| 54 | typedef pthread_cond_t native_type; | 54 | typedef pthread_cond_t native_type; |
| 55 | #endif | 55 | #endif |
| 56 | 56 | ||
| 57 | public: | 57 | public: |
| 58 | 58 | ||
| 59 | #ifdef USE_EVENTS | 59 | #ifdef USE_EVENTS |
| 60 | typedef native_type native_handle_type; | 60 | typedef native_type native_handle_type; |
| 61 | #else | 61 | #else |
| 62 | typedef native_type* native_handle_type; | 62 | typedef native_type* native_handle_type; |
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | condition_variable() | 65 | condition_variable() |
| 66 | { | 66 | { |
| 67 | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | 67 | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) |
| 68 | InitializeConditionVariable(&m_handle); | 68 | InitializeConditionVariable(&m_handle); |
| 69 | #elif defined(_WIN32) | 69 | #elif defined(_WIN32) |
| 70 | m_handle = CreateEvent(NULL, false, false, NULL); | 70 | m_handle = CreateEvent(NULL, false, false, NULL); |
| 71 | #else | 71 | #else |
| 72 | pthread_cond_init(&m_handle, NULL); | 72 | pthread_cond_init(&m_handle, NULL); |
| 73 | #endif | 73 | #endif |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | ~condition_variable() | 76 | ~condition_variable() |
| 77 | { | 77 | { |
| 78 | #if defined(_WIN32) && !defined(USE_CONDITION_VARIABLES) | 78 | #if defined(_WIN32) && !defined(USE_CONDITION_VARIABLES) |
| 79 | CloseHandle(m_handle); | 79 | CloseHandle(m_handle); |
| 80 | #elif !defined(_WIN32) | 80 | #elif !defined(_WIN32) |
| 81 | pthread_cond_destroy(&m_handle); | 81 | pthread_cond_destroy(&m_handle); |
| 82 | #endif | 82 | #endif |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | condition_variable(const condition_variable&) /*= delete*/; | 85 | condition_variable(const condition_variable&) /*= delete*/; |
| 86 | condition_variable& operator=(const condition_variable&) /*= delete*/; | 86 | condition_variable& operator=(const condition_variable&) /*= delete*/; |
| 87 | 87 | ||
| 88 | void notify_one() | 88 | void notify_one() |
| 89 | { | 89 | { |
| 90 | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | 90 | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) |
| 91 | WakeConditionVariable(&m_handle); | 91 | WakeConditionVariable(&m_handle); |
| 92 | #elif defined(_WIN32) | 92 | #elif defined(_WIN32) |
| 93 | SetEvent(m_handle); | 93 | SetEvent(m_handle); |
| 94 | #else | 94 | #else |
| 95 | pthread_cond_signal(&m_handle); | 95 | pthread_cond_signal(&m_handle); |
| 96 | #endif | 96 | #endif |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | void notify_all() | 99 | void notify_all() |
| 100 | { | 100 | { |
| 101 | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) | 101 | #if defined(_WIN32) && defined(USE_CONDITION_VARIABLES) |
| 102 | WakeAllConditionVariable(&m_handle); | 102 | WakeAllConditionVariable(&m_handle); |
| 103 | #elif defined(_WIN32) | 103 | #elif defined(_WIN32) |
| 104 | // TODO: broken | 104 | // TODO: broken |
| 105 | SetEvent(m_handle); | 105 | SetEvent(m_handle); |
| 106 | #else | 106 | #else |
| 107 | pthread_cond_broadcast(&m_handle); | 107 | pthread_cond_broadcast(&m_handle); |
| 108 | #endif | 108 | #endif |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | void wait(unique_lock<mutex>& lock) | 111 | void wait(unique_lock<mutex>& lock) |
| 112 | { | 112 | { |
| 113 | #ifdef _WIN32 | 113 | #ifdef _WIN32 |
| 114 | #ifdef USE_SRWLOCKS | 114 | #ifdef USE_SRWLOCKS |
| 115 | SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0); | 115 | SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0); |
| 116 | #elif defined(USE_CONDITION_VARIABLES) | 116 | #elif defined(USE_CONDITION_VARIABLES) |
| 117 | SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE); | 117 | SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE); |
| 118 | #else | 118 | #else |
| 119 | // TODO: broken, the unlock and wait need to be atomic | 119 | // TODO: broken, the unlock and wait need to be atomic |
| 120 | lock.unlock(); | 120 | lock.unlock(); |
| 121 | WaitForSingleObject(m_handle, INFINITE); | 121 | WaitForSingleObject(m_handle, INFINITE); |
| 122 | lock.lock(); | 122 | lock.lock(); |
| 123 | #endif | 123 | #endif |
| 124 | #else | 124 | #else |
| 125 | pthread_cond_wait(&m_handle, lock.mutex()->native_handle()); | 125 | pthread_cond_wait(&m_handle, lock.mutex()->native_handle()); |
| 126 | #endif | 126 | #endif |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | template <class Predicate> | 129 | template <class Predicate> |
| 130 | void wait(unique_lock<mutex>& lock, Predicate pred) | 130 | void wait(unique_lock<mutex>& lock, Predicate pred) |
| 131 | { | 131 | { |
| 132 | while (!pred()) | 132 | while (!pred()) |
| 133 | wait(lock); | 133 | wait(lock); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | //template <class Clock, class Duration> | 136 | //template <class Clock, class Duration> |
| 137 | //cv_status wait_until(unique_lock<mutex>& lock, | 137 | //cv_status wait_until(unique_lock<mutex>& lock, |
| 138 | // const chrono::time_point<Clock, Duration>& abs_time); | 138 | // const chrono::time_point<Clock, Duration>& abs_time); |
| 139 | 139 | ||
| 140 | //template <class Clock, class Duration, class Predicate> | 140 | //template <class Clock, class Duration, class Predicate> |
| 141 | // bool wait_until(unique_lock<mutex>& lock, | 141 | // bool wait_until(unique_lock<mutex>& lock, |
| 142 | // const chrono::time_point<Clock, Duration>& abs_time, | 142 | // const chrono::time_point<Clock, Duration>& abs_time, |
| 143 | // Predicate pred); | 143 | // Predicate pred); |
| 144 | 144 | ||
| 145 | //template <class Rep, class Period> | 145 | //template <class Rep, class Period> |
| 146 | //cv_status wait_for(unique_lock<mutex>& lock, | 146 | //cv_status wait_for(unique_lock<mutex>& lock, |
| 147 | // const chrono::duration<Rep, Period>& rel_time); | 147 | // const chrono::duration<Rep, Period>& rel_time); |
| 148 | 148 | ||
| 149 | //template <class Rep, class Period, class Predicate> | 149 | //template <class Rep, class Period, class Predicate> |
| 150 | // bool wait_for(unique_lock<mutex>& lock, | 150 | // bool wait_for(unique_lock<mutex>& lock, |
| 151 | // const chrono::duration<Rep, Period>& rel_time, | 151 | // const chrono::duration<Rep, Period>& rel_time, |
| 152 | // Predicate pred); | 152 | // Predicate pred); |
| 153 | 153 | ||
| 154 | native_handle_type native_handle() | 154 | native_handle_type native_handle() |
| 155 | { | 155 | { |
| 156 | #ifdef USE_EVENTS | 156 | #ifdef USE_EVENTS |
| 157 | return m_handle; | 157 | return m_handle; |
| 158 | #else | 158 | #else |
| 159 | return &m_handle; | 159 | return &m_handle; |
| 160 | #endif | 160 | #endif |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | private: | 163 | private: |
| 164 | native_type m_handle; | 164 | native_type m_handle; |
| 165 | }; | 165 | }; |
| 166 | 166 | ||
| 167 | } | 167 | } |
diff --git a/src/common/src/std_mutex.h b/src/common/src/std_mutex.h index ce46a2f59..26eb58b62 100644 --- a/src/common/src/std_mutex.h +++ b/src/common/src/std_mutex.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | #ifndef MUTEX_H_ | 2 | #ifndef MUTEX_H_ |
| 3 | #define MUTEX_H_ | 3 | #define MUTEX_H_ |
| 4 | 4 | ||
| 5 | #define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z)) | 5 | #define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z)) |
| 6 | #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) | 6 | #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) |
| 7 | 7 | ||
| 8 | #ifndef __has_include | 8 | #ifndef __has_include |
| @@ -46,72 +46,72 @@ namespace std | |||
| 46 | class recursive_mutex | 46 | class recursive_mutex |
| 47 | { | 47 | { |
| 48 | #ifdef _WIN32 | 48 | #ifdef _WIN32 |
| 49 | typedef CRITICAL_SECTION native_type; | 49 | typedef CRITICAL_SECTION native_type; |
| 50 | #else | 50 | #else |
| 51 | typedef pthread_mutex_t native_type; | 51 | typedef pthread_mutex_t native_type; |
| 52 | #endif | 52 | #endif |
| 53 | 53 | ||
| 54 | public: | 54 | public: |
| 55 | typedef native_type* native_handle_type; | 55 | typedef native_type* native_handle_type; |
| 56 | 56 | ||
| 57 | recursive_mutex(const recursive_mutex&) /*= delete*/; | 57 | recursive_mutex(const recursive_mutex&) /*= delete*/; |
| 58 | recursive_mutex& operator=(const recursive_mutex&) /*= delete*/; | 58 | recursive_mutex& operator=(const recursive_mutex&) /*= delete*/; |
| 59 | 59 | ||
| 60 | recursive_mutex() | 60 | recursive_mutex() |
| 61 | { | 61 | { |
| 62 | #ifdef _WIN32 | 62 | #ifdef _WIN32 |
| 63 | InitializeCriticalSection(&m_handle); | 63 | InitializeCriticalSection(&m_handle); |
| 64 | #else | 64 | #else |
| 65 | pthread_mutexattr_t attr; | 65 | pthread_mutexattr_t attr; |
| 66 | pthread_mutexattr_init(&attr); | 66 | pthread_mutexattr_init(&attr); |
| 67 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | 67 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); |
| 68 | pthread_mutex_init(&m_handle, &attr); | 68 | pthread_mutex_init(&m_handle, &attr); |
| 69 | #endif | 69 | #endif |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | ~recursive_mutex() | 72 | ~recursive_mutex() |
| 73 | { | 73 | { |
| 74 | #ifdef _WIN32 | 74 | #ifdef _WIN32 |
| 75 | DeleteCriticalSection(&m_handle); | 75 | DeleteCriticalSection(&m_handle); |
| 76 | #else | 76 | #else |
| 77 | pthread_mutex_destroy(&m_handle); | 77 | pthread_mutex_destroy(&m_handle); |
| 78 | #endif | 78 | #endif |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | void lock() | 81 | void lock() |
| 82 | { | 82 | { |
| 83 | #ifdef _WIN32 | 83 | #ifdef _WIN32 |
| 84 | EnterCriticalSection(&m_handle); | 84 | EnterCriticalSection(&m_handle); |
| 85 | #else | 85 | #else |
| 86 | pthread_mutex_lock(&m_handle); | 86 | pthread_mutex_lock(&m_handle); |
| 87 | #endif | 87 | #endif |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | void unlock() | 90 | void unlock() |
| 91 | { | 91 | { |
| 92 | #ifdef _WIN32 | 92 | #ifdef _WIN32 |
| 93 | LeaveCriticalSection(&m_handle); | 93 | LeaveCriticalSection(&m_handle); |
| 94 | #else | 94 | #else |
| 95 | pthread_mutex_unlock(&m_handle); | 95 | pthread_mutex_unlock(&m_handle); |
| 96 | #endif | 96 | #endif |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | bool try_lock() | 99 | bool try_lock() |
| 100 | { | 100 | { |
| 101 | #ifdef _WIN32 | 101 | #ifdef _WIN32 |
| 102 | return (0 != TryEnterCriticalSection(&m_handle)); | 102 | return (0 != TryEnterCriticalSection(&m_handle)); |
| 103 | #else | 103 | #else |
| 104 | return !pthread_mutex_trylock(&m_handle); | 104 | return !pthread_mutex_trylock(&m_handle); |
| 105 | #endif | 105 | #endif |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | native_handle_type native_handle() | 108 | native_handle_type native_handle() |
| 109 | { | 109 | { |
| 110 | return &m_handle; | 110 | return &m_handle; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | private: | 113 | private: |
| 114 | native_type m_handle; | 114 | native_type m_handle; |
| 115 | }; | 115 | }; |
| 116 | 116 | ||
| 117 | #if !defined(_WIN32) || defined(USE_SRWLOCKS) | 117 | #if !defined(_WIN32) || defined(USE_SRWLOCKS) |
| @@ -119,74 +119,74 @@ private: | |||
| 119 | class mutex | 119 | class mutex |
| 120 | { | 120 | { |
| 121 | #ifdef _WIN32 | 121 | #ifdef _WIN32 |
| 122 | typedef SRWLOCK native_type; | 122 | typedef SRWLOCK native_type; |
| 123 | #else | 123 | #else |
| 124 | typedef pthread_mutex_t native_type; | 124 | typedef pthread_mutex_t native_type; |
| 125 | #endif | 125 | #endif |
| 126 | 126 | ||
| 127 | public: | 127 | public: |
| 128 | typedef native_type* native_handle_type; | 128 | typedef native_type* native_handle_type; |
| 129 | 129 | ||
| 130 | mutex(const mutex&) /*= delete*/; | 130 | mutex(const mutex&) /*= delete*/; |
| 131 | mutex& operator=(const mutex&) /*= delete*/; | 131 | mutex& operator=(const mutex&) /*= delete*/; |
| 132 | 132 | ||
| 133 | mutex() | 133 | mutex() |
| 134 | { | 134 | { |
| 135 | #ifdef _WIN32 | 135 | #ifdef _WIN32 |
| 136 | InitializeSRWLock(&m_handle); | 136 | InitializeSRWLock(&m_handle); |
| 137 | #else | 137 | #else |
| 138 | pthread_mutex_init(&m_handle, NULL); | 138 | pthread_mutex_init(&m_handle, NULL); |
| 139 | #endif | 139 | #endif |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | ~mutex() | 142 | ~mutex() |
| 143 | { | 143 | { |
| 144 | #ifdef _WIN32 | 144 | #ifdef _WIN32 |
| 145 | #else | 145 | #else |
| 146 | pthread_mutex_destroy(&m_handle); | 146 | pthread_mutex_destroy(&m_handle); |
| 147 | #endif | 147 | #endif |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | void lock() | 150 | void lock() |
| 151 | { | 151 | { |
| 152 | #ifdef _WIN32 | 152 | #ifdef _WIN32 |
| 153 | AcquireSRWLockExclusive(&m_handle); | 153 | AcquireSRWLockExclusive(&m_handle); |
| 154 | #else | 154 | #else |
| 155 | pthread_mutex_lock(&m_handle); | 155 | pthread_mutex_lock(&m_handle); |
| 156 | #endif | 156 | #endif |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | void unlock() | 159 | void unlock() |
| 160 | { | 160 | { |
| 161 | #ifdef _WIN32 | 161 | #ifdef _WIN32 |
| 162 | ReleaseSRWLockExclusive(&m_handle); | 162 | ReleaseSRWLockExclusive(&m_handle); |
| 163 | #else | 163 | #else |
| 164 | pthread_mutex_unlock(&m_handle); | 164 | pthread_mutex_unlock(&m_handle); |
| 165 | #endif | 165 | #endif |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | bool try_lock() | 168 | bool try_lock() |
| 169 | { | 169 | { |
| 170 | #ifdef _WIN32 | 170 | #ifdef _WIN32 |
| 171 | // XXX TryAcquireSRWLockExclusive requires Windows 7! | 171 | // XXX TryAcquireSRWLockExclusive requires Windows 7! |
| 172 | // return (0 != TryAcquireSRWLockExclusive(&m_handle)); | 172 | // return (0 != TryAcquireSRWLockExclusive(&m_handle)); |
| 173 | return false; | 173 | return false; |
| 174 | #else | 174 | #else |
| 175 | return !pthread_mutex_trylock(&m_handle); | 175 | return !pthread_mutex_trylock(&m_handle); |
| 176 | #endif | 176 | #endif |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | native_handle_type native_handle() | 179 | native_handle_type native_handle() |
| 180 | { | 180 | { |
| 181 | return &m_handle; | 181 | return &m_handle; |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | private: | 184 | private: |
| 185 | native_type m_handle; | 185 | native_type m_handle; |
| 186 | }; | 186 | }; |
| 187 | 187 | ||
| 188 | #else | 188 | #else |
| 189 | typedef recursive_mutex mutex; // just use CriticalSections | 189 | typedef recursive_mutex mutex; // just use CriticalSections |
| 190 | 190 | ||
| 191 | #endif | 191 | #endif |
| 192 | 192 | ||
| @@ -198,165 +198,165 @@ template <class Mutex> | |||
| 198 | class lock_guard | 198 | class lock_guard |
| 199 | { | 199 | { |
| 200 | public: | 200 | public: |
| 201 | typedef Mutex mutex_type; | 201 | typedef Mutex mutex_type; |
| 202 | 202 | ||
| 203 | explicit lock_guard(mutex_type& m) | 203 | explicit lock_guard(mutex_type& m) |
| 204 | : pm(m) | 204 | : pm(m) |
| 205 | { | 205 | { |
| 206 | m.lock(); | 206 | m.lock(); |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | lock_guard(mutex_type& m, adopt_lock_t) | 209 | lock_guard(mutex_type& m, adopt_lock_t) |
| 210 | : pm(m) | 210 | : pm(m) |
| 211 | { | 211 | { |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | ~lock_guard() | 214 | ~lock_guard() |
| 215 | { | 215 | { |
| 216 | pm.unlock(); | 216 | pm.unlock(); |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | lock_guard(lock_guard const&) /*= delete*/; | 219 | lock_guard(lock_guard const&) /*= delete*/; |
| 220 | lock_guard& operator=(lock_guard const&) /*= delete*/; | 220 | lock_guard& operator=(lock_guard const&) /*= delete*/; |
| 221 | 221 | ||
| 222 | private: | 222 | private: |
| 223 | mutex_type& pm; | 223 | mutex_type& pm; |
| 224 | }; | 224 | }; |
| 225 | 225 | ||
| 226 | template <class Mutex> | 226 | template <class Mutex> |
| 227 | class unique_lock | 227 | class unique_lock |
| 228 | { | 228 | { |
| 229 | public: | 229 | public: |
| 230 | typedef Mutex mutex_type; | 230 | typedef Mutex mutex_type; |
| 231 | 231 | ||
| 232 | unique_lock() | 232 | unique_lock() |
| 233 | : pm(NULL), owns(false) | 233 | : pm(NULL), owns(false) |
| 234 | {} | 234 | {} |
| 235 | 235 | ||
| 236 | /*explicit*/ unique_lock(mutex_type& m) | 236 | /*explicit*/ unique_lock(mutex_type& m) |
| 237 | : pm(&m), owns(true) | 237 | : pm(&m), owns(true) |
| 238 | { | 238 | { |
| 239 | m.lock(); | 239 | m.lock(); |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | unique_lock(mutex_type& m, defer_lock_t) | 242 | unique_lock(mutex_type& m, defer_lock_t) |
| 243 | : pm(&m), owns(false) | 243 | : pm(&m), owns(false) |
| 244 | {} | 244 | {} |
| 245 | 245 | ||
| 246 | unique_lock(mutex_type& m, try_to_lock_t) | 246 | unique_lock(mutex_type& m, try_to_lock_t) |
| 247 | : pm(&m), owns(m.try_lock()) | 247 | : pm(&m), owns(m.try_lock()) |
| 248 | {} | 248 | {} |
| 249 | 249 | ||
| 250 | unique_lock(mutex_type& m, adopt_lock_t) | 250 | unique_lock(mutex_type& m, adopt_lock_t) |
| 251 | : pm(&m), owns(true) | 251 | : pm(&m), owns(true) |
| 252 | {} | 252 | {} |
| 253 | 253 | ||
| 254 | //template <class Clock, class Duration> | 254 | //template <class Clock, class Duration> |
| 255 | //unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); | 255 | //unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); |
| 256 | 256 | ||
| 257 | //template <class Rep, class Period> | 257 | //template <class Rep, class Period> |
| 258 | //unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); | 258 | //unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); |
| 259 | 259 | ||
| 260 | ~unique_lock() | 260 | ~unique_lock() |
| 261 | { | 261 | { |
| 262 | if (owns_lock()) | 262 | if (owns_lock()) |
| 263 | mutex()->unlock(); | 263 | mutex()->unlock(); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | #ifdef USE_RVALUE_REFERENCES | 266 | #ifdef USE_RVALUE_REFERENCES |
| 267 | unique_lock& operator=(const unique_lock&) /*= delete*/; | 267 | unique_lock& operator=(const unique_lock&) /*= delete*/; |
| 268 | 268 | ||
| 269 | unique_lock& operator=(unique_lock&& other) | 269 | unique_lock& operator=(unique_lock&& other) |
| 270 | { | 270 | { |
| 271 | #else | 271 | #else |
| 272 | unique_lock& operator=(const unique_lock& u) | 272 | unique_lock& operator=(const unique_lock& u) |
| 273 | { | 273 | { |
| 274 | // ugly const_cast to get around lack of rvalue references | 274 | // ugly const_cast to get around lack of rvalue references |
| 275 | unique_lock& other = const_cast<unique_lock&>(u); | 275 | unique_lock& other = const_cast<unique_lock&>(u); |
| 276 | #endif | 276 | #endif |
| 277 | swap(other); | 277 | swap(other); |
| 278 | return *this; | 278 | return *this; |
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | #ifdef USE_RVALUE_REFERENCES | 281 | #ifdef USE_RVALUE_REFERENCES |
| 282 | unique_lock(const unique_lock&) /*= delete*/; | 282 | unique_lock(const unique_lock&) /*= delete*/; |
| 283 | 283 | ||
| 284 | unique_lock(unique_lock&& other) | 284 | unique_lock(unique_lock&& other) |
| 285 | : pm(NULL), owns(false) | 285 | : pm(NULL), owns(false) |
| 286 | { | 286 | { |
| 287 | #else | 287 | #else |
| 288 | unique_lock(const unique_lock& u) | 288 | unique_lock(const unique_lock& u) |
| 289 | : pm(NULL), owns(false) | 289 | : pm(NULL), owns(false) |
| 290 | { | 290 | { |
| 291 | // ugly const_cast to get around lack of rvalue references | 291 | // ugly const_cast to get around lack of rvalue references |
| 292 | unique_lock& other = const_cast<unique_lock&>(u); | 292 | unique_lock& other = const_cast<unique_lock&>(u); |
| 293 | #endif | 293 | #endif |
| 294 | swap(other); | 294 | swap(other); |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | void lock() | 297 | void lock() |
| 298 | { | 298 | { |
| 299 | mutex()->lock(); | 299 | mutex()->lock(); |
| 300 | owns = true; | 300 | owns = true; |
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | bool try_lock() | 303 | bool try_lock() |
| 304 | { | 304 | { |
| 305 | owns = mutex()->try_lock(); | 305 | owns = mutex()->try_lock(); |
| 306 | return owns; | 306 | return owns; |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | //template <class Rep, class Period> | 309 | //template <class Rep, class Period> |
| 310 | //bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); | 310 | //bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); |
| 311 | //template <class Clock, class Duration> | 311 | //template <class Clock, class Duration> |
| 312 | //bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); | 312 | //bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); |
| 313 | 313 | ||
| 314 | void unlock() | 314 | void unlock() |
| 315 | { | 315 | { |
| 316 | mutex()->unlock(); | 316 | mutex()->unlock(); |
| 317 | owns = false; | 317 | owns = false; |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | void swap(unique_lock& u) | 320 | void swap(unique_lock& u) |
| 321 | { | 321 | { |
| 322 | std::swap(pm, u.pm); | 322 | std::swap(pm, u.pm); |
| 323 | std::swap(owns, u.owns); | 323 | std::swap(owns, u.owns); |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | mutex_type* release() | 326 | mutex_type* release() |
| 327 | { | 327 | { |
| 328 | auto const ret = mutex(); | 328 | auto const ret = mutex(); |
| 329 | 329 | ||
| 330 | pm = NULL; | 330 | pm = NULL; |
| 331 | owns = false; | 331 | owns = false; |
| 332 | 332 | ||
| 333 | return ret; | 333 | return ret; |
| 334 | } | 334 | } |
| 335 | 335 | ||
| 336 | bool owns_lock() const | 336 | bool owns_lock() const |
| 337 | { | 337 | { |
| 338 | return owns; | 338 | return owns; |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | //explicit operator bool () const | 341 | //explicit operator bool () const |
| 342 | //{ | 342 | //{ |
| 343 | // return owns_lock(); | 343 | // return owns_lock(); |
| 344 | //} | 344 | //} |
| 345 | 345 | ||
| 346 | mutex_type* mutex() const | 346 | mutex_type* mutex() const |
| 347 | { | 347 | { |
| 348 | return pm; | 348 | return pm; |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | private: | 351 | private: |
| 352 | mutex_type* pm; | 352 | mutex_type* pm; |
| 353 | bool owns; | 353 | bool owns; |
| 354 | }; | 354 | }; |
| 355 | 355 | ||
| 356 | template <class Mutex> | 356 | template <class Mutex> |
| 357 | void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) | 357 | void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) |
| 358 | { | 358 | { |
| 359 | x.swap(y); | 359 | x.swap(y); |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | } | 362 | } |
diff --git a/src/common/src/std_thread.h b/src/common/src/std_thread.h index e43d28344..9ed0072c3 100644 --- a/src/common/src/std_thread.h +++ b/src/common/src/std_thread.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | #ifndef STD_THREAD_H_ | 2 | #ifndef STD_THREAD_H_ |
| 3 | #define STD_THREAD_H_ | 3 | #define STD_THREAD_H_ |
| 4 | 4 | ||
| 5 | #define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z)) | 5 | #define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z)) |
| 6 | #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) | 6 | #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) |
| 7 | 7 | ||
| 8 | #ifndef __has_include | 8 | #ifndef __has_include |
| @@ -77,209 +77,209 @@ namespace std | |||
| 77 | class thread | 77 | class thread |
| 78 | { | 78 | { |
| 79 | public: | 79 | public: |
| 80 | typedef THREAD_HANDLE native_handle_type; | 80 | typedef THREAD_HANDLE native_handle_type; |
| 81 | 81 | ||
| 82 | class id | 82 | class id |
| 83 | { | 83 | { |
| 84 | friend class thread; | 84 | friend class thread; |
| 85 | public: | 85 | public: |
| 86 | id() : m_thread(0) {} | 86 | id() : m_thread(0) {} |
| 87 | id(THREAD_ID _id) : m_thread(_id) {} | 87 | id(THREAD_ID _id) : m_thread(_id) {} |
| 88 | 88 | ||
| 89 | bool operator==(const id& rhs) const | 89 | bool operator==(const id& rhs) const |
| 90 | { | 90 | { |
| 91 | return m_thread == rhs.m_thread; | 91 | return m_thread == rhs.m_thread; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | bool operator!=(const id& rhs) const | 94 | bool operator!=(const id& rhs) const |
| 95 | { | 95 | { |
| 96 | return !(*this == rhs); | 96 | return !(*this == rhs); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | bool operator<(const id& rhs) const | 99 | bool operator<(const id& rhs) const |
| 100 | { | 100 | { |
| 101 | return m_thread < rhs.m_thread; | 101 | return m_thread < rhs.m_thread; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | private: | 104 | private: |
| 105 | THREAD_ID m_thread; | 105 | THREAD_ID m_thread; |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | // no variadic template support in msvc | 108 | // no variadic template support in msvc |
| 109 | //template <typename C, typename... A> | 109 | //template <typename C, typename... A> |
| 110 | //thread(C&& func, A&&... args); | 110 | //thread(C&& func, A&&... args); |
| 111 | 111 | ||
| 112 | template <typename C> | 112 | template <typename C> |
| 113 | thread(C func) | 113 | thread(C func) |
| 114 | { | 114 | { |
| 115 | StartThread(new Func<C>(func)); | 115 | StartThread(new Func<C>(func)); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | template <typename C, typename A> | 118 | template <typename C, typename A> |
| 119 | thread(C func, A arg) | 119 | thread(C func, A arg) |
| 120 | { | 120 | { |
| 121 | StartThread(new FuncArg<C, A>(func, arg)); | 121 | StartThread(new FuncArg<C, A>(func, arg)); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | thread() /*= default;*/ {} | 124 | thread() /*= default;*/ {} |
| 125 | 125 | ||
| 126 | #ifdef USE_RVALUE_REFERENCES | 126 | #ifdef USE_RVALUE_REFERENCES |
| 127 | thread(const thread&) /*= delete*/; | 127 | thread(const thread&) /*= delete*/; |
| 128 | 128 | ||
| 129 | thread(thread&& other) | 129 | thread(thread&& other) |
| 130 | { | 130 | { |
| 131 | #else | 131 | #else |
| 132 | thread(const thread& t) | 132 | thread(const thread& t) |
| 133 | { | 133 | { |
| 134 | // ugly const_cast to get around lack of rvalue references | 134 | // ugly const_cast to get around lack of rvalue references |
| 135 | thread& other = const_cast<thread&>(t); | 135 | thread& other = const_cast<thread&>(t); |
| 136 | #endif | 136 | #endif |
| 137 | swap(other); | 137 | swap(other); |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | #ifdef USE_RVALUE_REFERENCES | 140 | #ifdef USE_RVALUE_REFERENCES |
| 141 | thread& operator=(const thread&) /*= delete*/; | 141 | thread& operator=(const thread&) /*= delete*/; |
| 142 | 142 | ||
| 143 | thread& operator=(thread&& other) | 143 | thread& operator=(thread&& other) |
| 144 | { | 144 | { |
| 145 | #else | 145 | #else |
| 146 | thread& operator=(const thread& t) | 146 | thread& operator=(const thread& t) |
| 147 | { | 147 | { |
| 148 | // ugly const_cast to get around lack of rvalue references | 148 | // ugly const_cast to get around lack of rvalue references |
| 149 | thread& other = const_cast<thread&>(t); | 149 | thread& other = const_cast<thread&>(t); |
| 150 | #endif | 150 | #endif |
| 151 | if (joinable()) | 151 | if (joinable()) |
| 152 | detach(); | 152 | detach(); |
| 153 | swap(other); | 153 | swap(other); |
| 154 | return *this; | 154 | return *this; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | ~thread() | 157 | ~thread() |
| 158 | { | 158 | { |
| 159 | if (joinable()) | 159 | if (joinable()) |
| 160 | detach(); | 160 | detach(); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | bool joinable() const | 163 | bool joinable() const |
| 164 | { | 164 | { |
| 165 | return m_id != id(); | 165 | return m_id != id(); |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | id get_id() const | 168 | id get_id() const |
| 169 | { | 169 | { |
| 170 | return m_id; | 170 | return m_id; |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | native_handle_type native_handle() | 173 | native_handle_type native_handle() |
| 174 | { | 174 | { |
| 175 | #ifdef _WIN32 | 175 | #ifdef _WIN32 |
| 176 | return m_handle; | 176 | return m_handle; |
| 177 | #else | 177 | #else |
| 178 | return m_id.m_thread; | 178 | return m_id.m_thread; |
| 179 | #endif | 179 | #endif |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | void join() | 182 | void join() |
| 183 | { | 183 | { |
| 184 | #ifdef _WIN32 | 184 | #ifdef _WIN32 |
| 185 | WaitForSingleObject(m_handle, INFINITE); | 185 | WaitForSingleObject(m_handle, INFINITE); |
| 186 | detach(); | 186 | detach(); |
| 187 | #else | 187 | #else |
| 188 | pthread_join(m_id.m_thread, NULL); | 188 | pthread_join(m_id.m_thread, NULL); |
| 189 | m_id = id(); | 189 | m_id = id(); |
| 190 | #endif | 190 | #endif |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | void detach() | 193 | void detach() |
| 194 | { | 194 | { |
| 195 | #ifdef _WIN32 | 195 | #ifdef _WIN32 |
| 196 | CloseHandle(m_handle); | 196 | CloseHandle(m_handle); |
| 197 | #else | 197 | #else |
| 198 | pthread_detach(m_id.m_thread); | 198 | pthread_detach(m_id.m_thread); |
| 199 | #endif | 199 | #endif |
| 200 | m_id = id(); | 200 | m_id = id(); |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | void swap(thread& other) | 203 | void swap(thread& other) |
| 204 | { | 204 | { |
| 205 | std::swap(m_id, other.m_id); | 205 | std::swap(m_id, other.m_id); |
| 206 | #ifdef _WIN32 | 206 | #ifdef _WIN32 |
| 207 | std::swap(m_handle, other.m_handle); | 207 | std::swap(m_handle, other.m_handle); |
| 208 | #endif | 208 | #endif |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | static unsigned hardware_concurrency() | 211 | static unsigned hardware_concurrency() |
| 212 | { | 212 | { |
| 213 | #ifdef _WIN32 | 213 | #ifdef _WIN32 |
| 214 | SYSTEM_INFO sysinfo; | 214 | SYSTEM_INFO sysinfo; |
| 215 | GetSystemInfo(&sysinfo); | 215 | GetSystemInfo(&sysinfo); |
| 216 | return static_cast<unsigned>(sysinfo.dwNumberOfProcessors); | 216 | return static_cast<unsigned>(sysinfo.dwNumberOfProcessors); |
| 217 | #else | 217 | #else |
| 218 | return 0; | 218 | return 0; |
| 219 | #endif | 219 | #endif |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | private: | 222 | private: |
| 223 | id m_id; | 223 | id m_id; |
| 224 | 224 | ||
| 225 | #ifdef _WIN32 | 225 | #ifdef _WIN32 |
| 226 | native_handle_type m_handle; | 226 | native_handle_type m_handle; |
| 227 | #endif | 227 | #endif |
| 228 | 228 | ||
| 229 | template <typename F> | 229 | template <typename F> |
| 230 | void StartThread(F* param) | 230 | void StartThread(F* param) |
| 231 | { | 231 | { |
| 232 | #ifdef USE_BEGINTHREADEX | 232 | #ifdef USE_BEGINTHREADEX |
| 233 | m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread); | 233 | m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread); |
| 234 | #elif defined(_WIN32) | 234 | #elif defined(_WIN32) |
| 235 | m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread); | 235 | m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread); |
| 236 | #else | 236 | #else |
| 237 | pthread_attr_t attr; | 237 | pthread_attr_t attr; |
| 238 | pthread_attr_init(&attr); | 238 | pthread_attr_init(&attr); |
| 239 | pthread_attr_setstacksize(&attr, 1024 * 1024); | 239 | pthread_attr_setstacksize(&attr, 1024 * 1024); |
| 240 | if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param)) | 240 | if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param)) |
| 241 | m_id = id(); | 241 | m_id = id(); |
| 242 | #endif | 242 | #endif |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | template <typename C> | 245 | template <typename C> |
| 246 | class Func | 246 | class Func |
| 247 | { | 247 | { |
| 248 | public: | 248 | public: |
| 249 | Func(C _func) : func(_func) {} | 249 | Func(C _func) : func(_func) {} |
| 250 | 250 | ||
| 251 | void Run() { func(); } | 251 | void Run() { func(); } |
| 252 | 252 | ||
| 253 | private: | 253 | private: |
| 254 | C const func; | 254 | C const func; |
| 255 | }; | 255 | }; |
| 256 | 256 | ||
| 257 | template <typename C, typename A> | 257 | template <typename C, typename A> |
| 258 | class FuncArg | 258 | class FuncArg |
| 259 | { | 259 | { |
| 260 | public: | 260 | public: |
| 261 | FuncArg(C _func, A _arg) : func(_func), arg(_arg) {} | 261 | FuncArg(C _func, A _arg) : func(_func), arg(_arg) {} |
| 262 | 262 | ||
| 263 | void Run() { func(arg); } | 263 | void Run() { func(arg); } |
| 264 | 264 | ||
| 265 | private: | 265 | private: |
| 266 | C const func; | 266 | C const func; |
| 267 | A arg; | 267 | A arg; |
| 268 | }; | 268 | }; |
| 269 | 269 | ||
| 270 | template <typename F> | 270 | template <typename F> |
| 271 | static THREAD_RETURN RunAndDelete(void* param) | 271 | static THREAD_RETURN RunAndDelete(void* param) |
| 272 | { | 272 | { |
| 273 | #ifdef __APPLE__ | 273 | #ifdef __APPLE__ |
| 274 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | 274 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
| 275 | #endif | 275 | #endif |
| 276 | static_cast<F*>(param)->Run(); | 276 | static_cast<F*>(param)->Run(); |
| 277 | delete static_cast<F*>(param); | 277 | delete static_cast<F*>(param); |
| 278 | #ifdef __APPLE__ | 278 | #ifdef __APPLE__ |
| 279 | [pool release]; | 279 | [pool release]; |
| 280 | #endif | 280 | #endif |
| 281 | return 0; | 281 | return 0; |
| 282 | } | 282 | } |
| 283 | }; | 283 | }; |
| 284 | 284 | ||
| 285 | namespace this_thread | 285 | namespace this_thread |
| @@ -288,24 +288,24 @@ namespace this_thread | |||
| 288 | inline void yield() | 288 | inline void yield() |
| 289 | { | 289 | { |
| 290 | #ifdef _WIN32 | 290 | #ifdef _WIN32 |
| 291 | SwitchToThread(); | 291 | SwitchToThread(); |
| 292 | #else | 292 | #else |
| 293 | sleep(0); | 293 | sleep(0); |
| 294 | #endif | 294 | #endif |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | inline thread::id get_id() | 297 | inline thread::id get_id() |
| 298 | { | 298 | { |
| 299 | #ifdef _WIN32 | 299 | #ifdef _WIN32 |
| 300 | return GetCurrentThreadId(); | 300 | return GetCurrentThreadId(); |
| 301 | #else | 301 | #else |
| 302 | return pthread_self(); | 302 | return pthread_self(); |
| 303 | #endif | 303 | #endif |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | } // namespace this_thread | 306 | } // namespace this_thread |
| 307 | 307 | ||
| 308 | } // namespace std | 308 | } // namespace std |
| 309 | 309 | ||
| 310 | #undef USE_RVALUE_REFERENCES | 310 | #undef USE_RVALUE_REFERENCES |
| 311 | #undef USE_BEGINTHREADEX | 311 | #undef USE_BEGINTHREADEX |
diff --git a/src/common/src/string_util.cpp b/src/common/src/string_util.cpp index ff4c5dbe0..415dcbbc7 100644 --- a/src/common/src/string_util.cpp +++ b/src/common/src/string_util.cpp | |||
| @@ -11,131 +11,131 @@ | |||
| 11 | #include "string_util.h" | 11 | #include "string_util.h" |
| 12 | 12 | ||
| 13 | #ifdef _WIN32 | 13 | #ifdef _WIN32 |
| 14 | #include <Windows.h> | 14 | #include <Windows.h> |
| 15 | #else | 15 | #else |
| 16 | #include <iconv.h> | 16 | #include <iconv.h> |
| 17 | #include <errno.h> | 17 | #include <errno.h> |
| 18 | #endif | 18 | #endif |
| 19 | 19 | ||
| 20 | // faster than sscanf | 20 | // faster than sscanf |
| 21 | bool AsciiToHex(const char* _szValue, u32& result) | 21 | bool AsciiToHex(const char* _szValue, u32& result) |
| 22 | { | 22 | { |
| 23 | char *endptr = NULL; | 23 | char *endptr = NULL; |
| 24 | const u32 value = strtoul(_szValue, &endptr, 16); | 24 | const u32 value = strtoul(_szValue, &endptr, 16); |
| 25 | 25 | ||
| 26 | if (!endptr || *endptr) | 26 | if (!endptr || *endptr) |
| 27 | return false; | 27 | return false; |
| 28 | 28 | ||
| 29 | result = value; | 29 | result = value; |
| 30 | return true; | 30 | return true; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) | 33 | bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) |
| 34 | { | 34 | { |
| 35 | int writtenCount; | 35 | int writtenCount; |
| 36 | 36 | ||
| 37 | #ifdef _WIN32 | 37 | #ifdef _WIN32 |
| 38 | // You would think *printf are simple, right? Iterate on each character, | 38 | // You would think *printf are simple, right? Iterate on each character, |
| 39 | // if it's a format specifier handle it properly, etc. | 39 | // if it's a format specifier handle it properly, etc. |
| 40 | // | 40 | // |
| 41 | // Nooooo. Not according to the C standard. | 41 | // Nooooo. Not according to the C standard. |
| 42 | // | 42 | // |
| 43 | // According to the C99 standard (7.19.6.1 "The fprintf function") | 43 | // According to the C99 standard (7.19.6.1 "The fprintf function") |
| 44 | // The format shall be a multibyte character sequence | 44 | // The format shall be a multibyte character sequence |
| 45 | // | 45 | // |
| 46 | // Because some character encodings might have '%' signs in the middle of | 46 | // Because some character encodings might have '%' signs in the middle of |
| 47 | // a multibyte sequence (SJIS for example only specifies that the first | 47 | // a multibyte sequence (SJIS for example only specifies that the first |
| 48 | // byte of a 2 byte sequence is "high", the second byte can be anything), | 48 | // byte of a 2 byte sequence is "high", the second byte can be anything), |
| 49 | // printf functions have to decode the multibyte sequences and try their | 49 | // printf functions have to decode the multibyte sequences and try their |
| 50 | // best to not screw up. | 50 | // best to not screw up. |
| 51 | // | 51 | // |
| 52 | // Unfortunately, on Windows, the locale for most languages is not UTF-8 | 52 | // Unfortunately, on Windows, the locale for most languages is not UTF-8 |
| 53 | // as we would need. Notably, for zh_TW, Windows chooses EUC-CN as the | 53 | // as we would need. Notably, for zh_TW, Windows chooses EUC-CN as the |
| 54 | // locale, and completely fails when trying to decode UTF-8 as EUC-CN. | 54 | // locale, and completely fails when trying to decode UTF-8 as EUC-CN. |
| 55 | // | 55 | // |
| 56 | // On the other hand, the fix is simple: because we use UTF-8, no such | 56 | // On the other hand, the fix is simple: because we use UTF-8, no such |
| 57 | // multibyte handling is required as we can simply assume that no '%' char | 57 | // multibyte handling is required as we can simply assume that no '%' char |
| 58 | // will be present in the middle of a multibyte sequence. | 58 | // will be present in the middle of a multibyte sequence. |
| 59 | // | 59 | // |
| 60 | // This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l. | 60 | // This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l. |
| 61 | static locale_t c_locale = NULL; | 61 | static locale_t c_locale = NULL; |
| 62 | if (!c_locale) | 62 | if (!c_locale) |
| 63 | c_locale = _create_locale(LC_ALL, ".1252"); | 63 | c_locale = _create_locale(LC_ALL, ".1252"); |
| 64 | writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); | 64 | writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); |
| 65 | #else | 65 | #else |
| 66 | writtenCount = vsnprintf(out, outsize, format, args); | 66 | writtenCount = vsnprintf(out, outsize, format, args); |
| 67 | #endif | 67 | #endif |
| 68 | 68 | ||
| 69 | if (writtenCount > 0 && writtenCount < outsize) | 69 | if (writtenCount > 0 && writtenCount < outsize) |
| 70 | { | 70 | { |
| 71 | out[writtenCount] = '\0'; | 71 | out[writtenCount] = '\0'; |
| 72 | return true; | 72 | return true; |
| 73 | } | 73 | } |
| 74 | else | 74 | else |
| 75 | { | 75 | { |
| 76 | out[outsize - 1] = '\0'; | 76 | out[outsize - 1] = '\0'; |
| 77 | return false; | 77 | return false; |
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | std::string StringFromFormat(const char* format, ...) | 81 | std::string StringFromFormat(const char* format, ...) |
| 82 | { | 82 | { |
| 83 | va_list args; | 83 | va_list args; |
| 84 | char *buf = NULL; | 84 | char *buf = NULL; |
| 85 | #ifdef _WIN32 | 85 | #ifdef _WIN32 |
| 86 | int required = 0; | 86 | int required = 0; |
| 87 | 87 | ||
| 88 | va_start(args, format); | 88 | va_start(args, format); |
| 89 | required = _vscprintf(format, args); | 89 | required = _vscprintf(format, args); |
| 90 | buf = new char[required + 1]; | 90 | buf = new char[required + 1]; |
| 91 | CharArrayFromFormatV(buf, required + 1, format, args); | 91 | CharArrayFromFormatV(buf, required + 1, format, args); |
| 92 | va_end(args); | 92 | va_end(args); |
| 93 | 93 | ||
| 94 | std::string temp = buf; | 94 | std::string temp = buf; |
| 95 | delete[] buf; | 95 | delete[] buf; |
| 96 | #else | 96 | #else |
| 97 | va_start(args, format); | 97 | va_start(args, format); |
| 98 | if (vasprintf(&buf, format, args) < 0) | 98 | if (vasprintf(&buf, format, args) < 0) |
| 99 | ERROR_LOG(COMMON, "Unable to allocate memory for string"); | 99 | ERROR_LOG(COMMON, "Unable to allocate memory for string"); |
| 100 | va_end(args); | 100 | va_end(args); |
| 101 | 101 | ||
| 102 | std::string temp = buf; | 102 | std::string temp = buf; |
| 103 | free(buf); | 103 | free(buf); |
| 104 | #endif | 104 | #endif |
| 105 | return temp; | 105 | return temp; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | // For Debugging. Read out an u8 array. | 108 | // For Debugging. Read out an u8 array. |
| 109 | std::string ArrayToString(const u8 *data, u32 size, int line_len, bool spaces) | 109 | std::string ArrayToString(const u8 *data, u32 size, int line_len, bool spaces) |
| 110 | { | 110 | { |
| 111 | std::ostringstream oss; | 111 | std::ostringstream oss; |
| 112 | oss << std::setfill('0') << std::hex; | 112 | oss << std::setfill('0') << std::hex; |
| 113 | 113 | ||
| 114 | for (int line = 0; size; ++data, --size) | 114 | for (int line = 0; size; ++data, --size) |
| 115 | { | 115 | { |
| 116 | oss << std::setw(2) << (int)*data; | 116 | oss << std::setw(2) << (int)*data; |
| 117 | 117 | ||
| 118 | if (line_len == ++line) | 118 | if (line_len == ++line) |
| 119 | { | 119 | { |
| 120 | oss << '\n'; | 120 | oss << '\n'; |
| 121 | line = 0; | 121 | line = 0; |
| 122 | } | 122 | } |
| 123 | else if (spaces) | 123 | else if (spaces) |
| 124 | oss << ' '; | 124 | oss << ' '; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | return oss.str(); | 127 | return oss.str(); |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | // Turns " hej " into "hej". Also handles tabs. | 130 | // Turns " hej " into "hej". Also handles tabs. |
| 131 | std::string StripSpaces(const std::string &str) | 131 | std::string StripSpaces(const std::string &str) |
| 132 | { | 132 | { |
| 133 | const size_t s = str.find_first_not_of(" \t\r\n"); | 133 | const size_t s = str.find_first_not_of(" \t\r\n"); |
| 134 | 134 | ||
| 135 | if (str.npos != s) | 135 | if (str.npos != s) |
| 136 | return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); | 136 | return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); |
| 137 | else | 137 | else |
| 138 | return ""; | 138 | return ""; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | // "\"hello\"" is turned to "hello" | 141 | // "\"hello\"" is turned to "hello" |
| @@ -143,137 +143,137 @@ std::string StripSpaces(const std::string &str) | |||
| 143 | // ends, as done by StripSpaces above, for example. | 143 | // ends, as done by StripSpaces above, for example. |
| 144 | std::string StripQuotes(const std::string& s) | 144 | std::string StripQuotes(const std::string& s) |
| 145 | { | 145 | { |
| 146 | if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) | 146 | if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) |
| 147 | return s.substr(1, s.size() - 2); | 147 | return s.substr(1, s.size() - 2); |
| 148 | else | 148 | else |
| 149 | return s; | 149 | return s; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | bool TryParse(const std::string &str, u32 *const output) | 152 | bool TryParse(const std::string &str, u32 *const output) |
| 153 | { | 153 | { |
| 154 | char *endptr = NULL; | 154 | char *endptr = NULL; |
| 155 | 155 | ||
| 156 | // Reset errno to a value other than ERANGE | 156 | // Reset errno to a value other than ERANGE |
| 157 | errno = 0; | 157 | errno = 0; |
| 158 | 158 | ||
| 159 | unsigned long value = strtoul(str.c_str(), &endptr, 0); | 159 | unsigned long value = strtoul(str.c_str(), &endptr, 0); |
| 160 | 160 | ||
| 161 | if (!endptr || *endptr) | 161 | if (!endptr || *endptr) |
| 162 | return false; | 162 | return false; |
| 163 | 163 | ||
| 164 | if (errno == ERANGE) | 164 | if (errno == ERANGE) |
| 165 | return false; | 165 | return false; |
| 166 | 166 | ||
| 167 | #if ULONG_MAX > UINT_MAX | 167 | #if ULONG_MAX > UINT_MAX |
| 168 | if (value >= 0x100000000ull | 168 | if (value >= 0x100000000ull |
| 169 | && value <= 0xFFFFFFFF00000000ull) | 169 | && value <= 0xFFFFFFFF00000000ull) |
| 170 | return false; | 170 | return false; |
| 171 | #endif | 171 | #endif |
| 172 | 172 | ||
| 173 | *output = static_cast<u32>(value); | 173 | *output = static_cast<u32>(value); |
| 174 | return true; | 174 | return true; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | bool TryParse(const std::string &str, bool *const output) | 177 | bool TryParse(const std::string &str, bool *const output) |
| 178 | { | 178 | { |
| 179 | if ("1" == str || !strcasecmp("true", str.c_str())) | 179 | if ("1" == str || !strcasecmp("true", str.c_str())) |
| 180 | *output = true; | 180 | *output = true; |
| 181 | else if ("0" == str || !strcasecmp("false", str.c_str())) | 181 | else if ("0" == str || !strcasecmp("false", str.c_str())) |
| 182 | *output = false; | 182 | *output = false; |
| 183 | else | 183 | else |
| 184 | return false; | 184 | return false; |
| 185 | 185 | ||
| 186 | return true; | 186 | return true; |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | std::string StringFromInt(int value) | 189 | std::string StringFromInt(int value) |
| 190 | { | 190 | { |
| 191 | char temp[16]; | 191 | char temp[16]; |
| 192 | sprintf(temp, "%i", value); | 192 | sprintf(temp, "%i", value); |
| 193 | return temp; | 193 | return temp; |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | std::string StringFromBool(bool value) | 196 | std::string StringFromBool(bool value) |
| 197 | { | 197 | { |
| 198 | return value ? "True" : "False"; | 198 | return value ? "True" : "False"; |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension) | 201 | bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension) |
| 202 | { | 202 | { |
| 203 | if (full_path.empty()) | 203 | if (full_path.empty()) |
| 204 | return false; | 204 | return false; |
| 205 | 205 | ||
| 206 | size_t dir_end = full_path.find_last_of("/" | 206 | size_t dir_end = full_path.find_last_of("/" |
| 207 | // windows needs the : included for something like just "C:" to be considered a directory | 207 | // windows needs the : included for something like just "C:" to be considered a directory |
| 208 | #ifdef _WIN32 | 208 | #ifdef _WIN32 |
| 209 | ":" | 209 | ":" |
| 210 | #endif | 210 | #endif |
| 211 | ); | 211 | ); |
| 212 | if (std::string::npos == dir_end) | 212 | if (std::string::npos == dir_end) |
| 213 | dir_end = 0; | 213 | dir_end = 0; |
| 214 | else | 214 | else |
| 215 | dir_end += 1; | 215 | dir_end += 1; |
| 216 | 216 | ||
| 217 | size_t fname_end = full_path.rfind('.'); | 217 | size_t fname_end = full_path.rfind('.'); |
| 218 | if (fname_end < dir_end || std::string::npos == fname_end) | 218 | if (fname_end < dir_end || std::string::npos == fname_end) |
| 219 | fname_end = full_path.size(); | 219 | fname_end = full_path.size(); |
| 220 | 220 | ||
| 221 | if (_pPath) | 221 | if (_pPath) |
| 222 | *_pPath = full_path.substr(0, dir_end); | 222 | *_pPath = full_path.substr(0, dir_end); |
| 223 | 223 | ||
| 224 | if (_pFilename) | 224 | if (_pFilename) |
| 225 | *_pFilename = full_path.substr(dir_end, fname_end - dir_end); | 225 | *_pFilename = full_path.substr(dir_end, fname_end - dir_end); |
| 226 | 226 | ||
| 227 | if (_pExtension) | 227 | if (_pExtension) |
| 228 | *_pExtension = full_path.substr(fname_end); | 228 | *_pExtension = full_path.substr(fname_end); |
| 229 | 229 | ||
| 230 | return true; | 230 | return true; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, const std::string& _Filename) | 233 | void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, const std::string& _Filename) |
| 234 | { | 234 | { |
| 235 | _CompleteFilename = _Path; | 235 | _CompleteFilename = _Path; |
| 236 | 236 | ||
| 237 | // check for seperator | 237 | // check for seperator |
| 238 | if (DIR_SEP_CHR != *_CompleteFilename.rbegin()) | 238 | if (DIR_SEP_CHR != *_CompleteFilename.rbegin()) |
| 239 | _CompleteFilename += DIR_SEP_CHR; | 239 | _CompleteFilename += DIR_SEP_CHR; |
| 240 | 240 | ||
| 241 | // add the filename | 241 | // add the filename |
| 242 | _CompleteFilename += _Filename; | 242 | _CompleteFilename += _Filename; |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | void SplitString(const std::string& str, const char delim, std::vector<std::string>& output) | 245 | void SplitString(const std::string& str, const char delim, std::vector<std::string>& output) |
| 246 | { | 246 | { |
| 247 | std::istringstream iss(str); | 247 | std::istringstream iss(str); |
| 248 | output.resize(1); | 248 | output.resize(1); |
| 249 | 249 | ||
| 250 | while (std::getline(iss, *output.rbegin(), delim)) | 250 | while (std::getline(iss, *output.rbegin(), delim)) |
| 251 | output.push_back(""); | 251 | output.push_back(""); |
| 252 | 252 | ||
| 253 | output.pop_back(); | 253 | output.pop_back(); |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | std::string TabsToSpaces(int tab_size, const std::string &in) | 256 | std::string TabsToSpaces(int tab_size, const std::string &in) |
| 257 | { | 257 | { |
| 258 | const std::string spaces(tab_size, ' '); | 258 | const std::string spaces(tab_size, ' '); |
| 259 | std::string out(in); | 259 | std::string out(in); |
| 260 | 260 | ||
| 261 | size_t i = 0; | 261 | size_t i = 0; |
| 262 | while (out.npos != (i = out.find('\t'))) | 262 | while (out.npos != (i = out.find('\t'))) |
| 263 | out.replace(i, 1, spaces); | 263 | out.replace(i, 1, spaces); |
| 264 | 264 | ||
| 265 | return out; | 265 | return out; |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) | 268 | std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) |
| 269 | { | 269 | { |
| 270 | while(1) | 270 | while(1) |
| 271 | { | 271 | { |
| 272 | size_t pos = result.find(src); | 272 | size_t pos = result.find(src); |
| 273 | if (pos == std::string::npos) break; | 273 | if (pos == std::string::npos) break; |
| 274 | result.replace(pos, src.size(), dest); | 274 | result.replace(pos, src.size(), dest); |
| 275 | } | 275 | } |
| 276 | return result; | 276 | return result; |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | // UriDecode and UriEncode are from http://www.codeguru.com/cpp/cpp/string/conversions/print.php/c12759 | 279 | // 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 | |||
| 287 | 287 | ||
| 288 | const char HEX2DEC[256] = | 288 | const char HEX2DEC[256] = |
| 289 | { | 289 | { |
| 290 | /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ | 290 | /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
| 291 | /* 0 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 291 | /* 0 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 292 | /* 1 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 292 | /* 1 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 293 | /* 2 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 293 | /* 2 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 294 | /* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,16,16, 16,16,16,16, | 294 | /* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,16,16, 16,16,16,16, |
| 295 | 295 | ||
| 296 | /* 4 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16, | 296 | /* 4 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16, |
| 297 | /* 5 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 297 | /* 5 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 298 | /* 6 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16, | 298 | /* 6 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16, |
| 299 | /* 7 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 299 | /* 7 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 300 | 300 | ||
| 301 | /* 8 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 301 | /* 8 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 302 | /* 9 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 302 | /* 9 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 303 | /* A */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 303 | /* A */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 304 | /* B */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 304 | /* B */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 305 | 305 | ||
| 306 | /* C */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 306 | /* C */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 307 | /* D */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 307 | /* D */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 308 | /* E */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, | 308 | /* E */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, |
| 309 | /* F */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16 | 309 | /* F */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16 |
| 310 | }; | 310 | }; |
| 311 | 311 | ||
| 312 | std::string UriDecode(const std::string & sSrc) | 312 | std::string UriDecode(const std::string & sSrc) |
| 313 | { | 313 | { |
| 314 | // Note from RFC1630: "Sequences which start with a percent sign | 314 | // Note from RFC1630: "Sequences which start with a percent sign |
| 315 | // but are not followed by two hexadecimal characters (0-9, A-F) are reserved | 315 | // but are not followed by two hexadecimal characters (0-9, A-F) are reserved |
| 316 | // for future extension" | 316 | // for future extension" |
| 317 | 317 | ||
| 318 | const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); | 318 | const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); |
| 319 | const size_t SRC_LEN = sSrc.length(); | 319 | const size_t SRC_LEN = sSrc.length(); |
| 320 | const unsigned char * const SRC_END = pSrc + SRC_LEN; | 320 | const unsigned char * const SRC_END = pSrc + SRC_LEN; |
| 321 | const unsigned char * const SRC_LAST_DEC = SRC_END - 2; // last decodable '%' | 321 | const unsigned char * const SRC_LAST_DEC = SRC_END - 2; // last decodable '%' |
| 322 | 322 | ||
| 323 | char * const pStart = new char[SRC_LEN]; | 323 | char * const pStart = new char[SRC_LEN]; |
| 324 | char * pEnd = pStart; | 324 | char * pEnd = pStart; |
| 325 | 325 | ||
| 326 | while (pSrc < SRC_LAST_DEC) | 326 | while (pSrc < SRC_LAST_DEC) |
| 327 | { | 327 | { |
| 328 | if (*pSrc == '%') | 328 | if (*pSrc == '%') |
| 329 | { | 329 | { |
| 330 | char dec1, dec2; | 330 | char dec1, dec2; |
| 331 | if (16 != (dec1 = HEX2DEC[*(pSrc + 1)]) | 331 | if (16 != (dec1 = HEX2DEC[*(pSrc + 1)]) |
| 332 | && 16 != (dec2 = HEX2DEC[*(pSrc + 2)])) | 332 | && 16 != (dec2 = HEX2DEC[*(pSrc + 2)])) |
| 333 | { | 333 | { |
| 334 | *pEnd++ = (dec1 << 4) + dec2; | 334 | *pEnd++ = (dec1 << 4) + dec2; |
| 335 | pSrc += 3; | 335 | pSrc += 3; |
| 336 | continue; | 336 | continue; |
| 337 | } | 337 | } |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | *pEnd++ = *pSrc++; | 340 | *pEnd++ = *pSrc++; |
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | // the last 2- chars | 343 | // the last 2- chars |
| 344 | while (pSrc < SRC_END) | 344 | while (pSrc < SRC_END) |
| 345 | *pEnd++ = *pSrc++; | 345 | *pEnd++ = *pSrc++; |
| 346 | 346 | ||
| 347 | std::string sResult(pStart, pEnd); | 347 | std::string sResult(pStart, pEnd); |
| 348 | delete [] pStart; | 348 | delete [] pStart; |
| 349 | return sResult; | 349 | return sResult; |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | // Only alphanum is safe. | 352 | // Only alphanum is safe. |
| 353 | const char SAFE[256] = | 353 | const char SAFE[256] = |
| 354 | { | 354 | { |
| 355 | /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ | 355 | /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
| 356 | /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | 356 | /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| 357 | /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | 357 | /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| 358 | /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | 358 | /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| 359 | /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, | 359 | /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, |
| 360 | 360 | ||
| 361 | /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, | 361 | /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, |
| 362 | /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, | 362 | /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, |
| 363 | /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, | 363 | /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, |
| 364 | /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, | 364 | /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, |
| 365 | 365 | ||
| 366 | /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | 366 | /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| 367 | /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | 367 | /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| 368 | /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | 368 | /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| 369 | /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | 369 | /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| 370 | 370 | ||
| 371 | /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | 371 | /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| 372 | /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | 372 | /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| 373 | /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | 373 | /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| 374 | /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 | 374 | /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 |
| 375 | }; | 375 | }; |
| 376 | 376 | ||
| 377 | std::string UriEncode(const std::string & sSrc) | 377 | std::string UriEncode(const std::string & sSrc) |
| 378 | { | 378 | { |
| 379 | const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; | 379 | const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; |
| 380 | const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); | 380 | const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); |
| 381 | const size_t SRC_LEN = sSrc.length(); | 381 | const size_t SRC_LEN = sSrc.length(); |
| 382 | unsigned char * const pStart = new unsigned char[SRC_LEN * 3]; | 382 | unsigned char * const pStart = new unsigned char[SRC_LEN * 3]; |
| 383 | unsigned char * pEnd = pStart; | 383 | unsigned char * pEnd = pStart; |
| 384 | const unsigned char * const SRC_END = pSrc + SRC_LEN; | 384 | const unsigned char * const SRC_END = pSrc + SRC_LEN; |
| 385 | 385 | ||
| 386 | for (; pSrc < SRC_END; ++pSrc) | 386 | for (; pSrc < SRC_END; ++pSrc) |
| 387 | { | 387 | { |
| 388 | if (SAFE[*pSrc]) | 388 | if (SAFE[*pSrc]) |
| 389 | *pEnd++ = *pSrc; | 389 | *pEnd++ = *pSrc; |
| 390 | else | 390 | else |
| 391 | { | 391 | { |
| 392 | // escape this char | 392 | // escape this char |
| 393 | *pEnd++ = '%'; | 393 | *pEnd++ = '%'; |
| 394 | *pEnd++ = DEC2HEX[*pSrc >> 4]; | 394 | *pEnd++ = DEC2HEX[*pSrc >> 4]; |
| 395 | *pEnd++ = DEC2HEX[*pSrc & 0x0F]; | 395 | *pEnd++ = DEC2HEX[*pSrc & 0x0F]; |
| 396 | } | 396 | } |
| 397 | } | 397 | } |
| 398 | 398 | ||
| 399 | std::string sResult((char *)pStart, (char *)pEnd); | 399 | std::string sResult((char *)pStart, (char *)pEnd); |
| 400 | delete [] pStart; | 400 | delete [] pStart; |
| 401 | return sResult; | 401 | return sResult; |
| 402 | } | 402 | } |
| 403 | 403 | ||
| 404 | #ifdef _WIN32 | 404 | #ifdef _WIN32 |
| 405 | 405 | ||
| 406 | std::string UTF16ToUTF8(const std::wstring& input) | 406 | std::string UTF16ToUTF8(const std::wstring& input) |
| 407 | { | 407 | { |
| 408 | auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), nullptr, 0, nullptr, nullptr); | 408 | auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), nullptr, 0, nullptr, nullptr); |
| 409 | 409 | ||
| 410 | std::string output; | 410 | std::string output; |
| 411 | output.resize(size); | 411 | output.resize(size); |
| 412 | 412 | ||
| 413 | if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr)) | 413 | if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr)) |
| 414 | output.clear(); | 414 | output.clear(); |
| 415 | 415 | ||
| 416 | return output; | 416 | return output; |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | std::wstring CPToUTF16(u32 code_page, const std::string& input) | 419 | std::wstring CPToUTF16(u32 code_page, const std::string& input) |
| 420 | { | 420 | { |
| 421 | auto const size = MultiByteToWideChar(code_page, 0, input.data(), input.size(), nullptr, 0); | 421 | auto const size = MultiByteToWideChar(code_page, 0, input.data(), input.size(), nullptr, 0); |
| 422 | 422 | ||
| 423 | std::wstring output; | 423 | std::wstring output; |
| 424 | output.resize(size); | 424 | output.resize(size); |
| 425 | 425 | ||
| 426 | if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size())) | 426 | if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size())) |
| 427 | output.clear(); | 427 | output.clear(); |
| 428 | 428 | ||
| 429 | return output; | 429 | return output; |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | std::wstring UTF8ToUTF16(const std::string& input) | 432 | std::wstring UTF8ToUTF16(const std::string& input) |
| 433 | { | 433 | { |
| 434 | return CPToUTF16(CP_UTF8, input); | 434 | return CPToUTF16(CP_UTF8, input); |
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | std::string SHIFTJISToUTF8(const std::string& input) | 437 | std::string SHIFTJISToUTF8(const std::string& input) |
| 438 | { | 438 | { |
| 439 | return UTF16ToUTF8(CPToUTF16(932, input)); | 439 | return UTF16ToUTF8(CPToUTF16(932, input)); |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | std::string CP1252ToUTF8(const std::string& input) | 442 | std::string CP1252ToUTF8(const std::string& input) |
| 443 | { | 443 | { |
| 444 | return UTF16ToUTF8(CPToUTF16(1252, input)); | 444 | return UTF16ToUTF8(CPToUTF16(1252, input)); |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | #else | 447 | #else |
| @@ -449,83 +449,83 @@ std::string CP1252ToUTF8(const std::string& input) | |||
| 449 | template <typename T> | 449 | template <typename T> |
| 450 | std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& input) | 450 | std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& input) |
| 451 | { | 451 | { |
| 452 | std::string result; | 452 | std::string result; |
| 453 | 453 | ||
| 454 | iconv_t const conv_desc = iconv_open("UTF-8", fromcode); | 454 | iconv_t const conv_desc = iconv_open("UTF-8", fromcode); |
| 455 | if ((iconv_t)-1 == conv_desc) | 455 | if ((iconv_t)-1 == conv_desc) |
| 456 | { | 456 | { |
| 457 | ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno)); | 457 | ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno)); |
| 458 | } | 458 | } |
| 459 | else | 459 | else |
| 460 | { | 460 | { |
| 461 | size_t const in_bytes = sizeof(T) * input.size(); | 461 | size_t const in_bytes = sizeof(T) * input.size(); |
| 462 | size_t const out_buffer_size = 4 * in_bytes; | 462 | size_t const out_buffer_size = 4 * in_bytes; |
| 463 | 463 | ||
| 464 | std::string out_buffer; | 464 | std::string out_buffer; |
| 465 | out_buffer.resize(out_buffer_size); | 465 | out_buffer.resize(out_buffer_size); |
| 466 | 466 | ||
| 467 | auto src_buffer = &input[0]; | 467 | auto src_buffer = &input[0]; |
| 468 | size_t src_bytes = in_bytes; | 468 | size_t src_bytes = in_bytes; |
| 469 | auto dst_buffer = &out_buffer[0]; | 469 | auto dst_buffer = &out_buffer[0]; |
| 470 | size_t dst_bytes = out_buffer.size(); | 470 | size_t dst_bytes = out_buffer.size(); |
| 471 | 471 | ||
| 472 | while (src_bytes != 0) | 472 | while (src_bytes != 0) |
| 473 | { | 473 | { |
| 474 | size_t const iconv_result = iconv(conv_desc, (char**)(&src_buffer), &src_bytes, | 474 | size_t const iconv_result = iconv(conv_desc, (char**)(&src_buffer), &src_bytes, |
| 475 | &dst_buffer, &dst_bytes); | 475 | &dst_buffer, &dst_bytes); |
| 476 | 476 | ||
| 477 | if ((size_t)-1 == iconv_result) | 477 | if ((size_t)-1 == iconv_result) |
| 478 | { | 478 | { |
| 479 | if (EILSEQ == errno || EINVAL == errno) | 479 | if (EILSEQ == errno || EINVAL == errno) |
| 480 | { | 480 | { |
| 481 | // Try to skip the bad character | 481 | // Try to skip the bad character |
| 482 | if (src_bytes != 0) | 482 | if (src_bytes != 0) |
| 483 | { | 483 | { |
| 484 | --src_bytes; | 484 | --src_bytes; |
| 485 | ++src_buffer; | 485 | ++src_buffer; |
| 486 | } | 486 | } |
| 487 | } | 487 | } |
| 488 | else | 488 | else |
| 489 | { | 489 | { |
| 490 | ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno)); | 490 | ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno)); |
| 491 | break; | 491 | break; |
| 492 | } | 492 | } |
| 493 | } | 493 | } |
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | out_buffer.resize(out_buffer_size - dst_bytes); | 496 | out_buffer.resize(out_buffer_size - dst_bytes); |
| 497 | out_buffer.swap(result); | 497 | out_buffer.swap(result); |
| 498 | 498 | ||
| 499 | iconv_close(conv_desc); | 499 | iconv_close(conv_desc); |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | return result; | 502 | return result; |
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | std::string CP1252ToUTF8(const std::string& input) | 505 | std::string CP1252ToUTF8(const std::string& input) |
| 506 | { | 506 | { |
| 507 | //return CodeToUTF8("CP1252//TRANSLIT", input); | 507 | //return CodeToUTF8("CP1252//TRANSLIT", input); |
| 508 | //return CodeToUTF8("CP1252//IGNORE", input); | 508 | //return CodeToUTF8("CP1252//IGNORE", input); |
| 509 | return CodeToUTF8("CP1252", input); | 509 | return CodeToUTF8("CP1252", input); |
| 510 | } | 510 | } |
| 511 | 511 | ||
| 512 | std::string SHIFTJISToUTF8(const std::string& input) | 512 | std::string SHIFTJISToUTF8(const std::string& input) |
| 513 | { | 513 | { |
| 514 | //return CodeToUTF8("CP932", input); | 514 | //return CodeToUTF8("CP932", input); |
| 515 | return CodeToUTF8("SJIS", input); | 515 | return CodeToUTF8("SJIS", input); |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | std::string UTF16ToUTF8(const std::wstring& input) | 518 | std::string UTF16ToUTF8(const std::wstring& input) |
| 519 | { | 519 | { |
| 520 | std::string result = | 520 | std::string result = |
| 521 | // CodeToUTF8("UCS-2", input); | 521 | // CodeToUTF8("UCS-2", input); |
| 522 | // CodeToUTF8("UCS-2LE", input); | 522 | // CodeToUTF8("UCS-2LE", input); |
| 523 | // CodeToUTF8("UTF-16", input); | 523 | // CodeToUTF8("UTF-16", input); |
| 524 | CodeToUTF8("UTF-16LE", input); | 524 | CodeToUTF8("UTF-16LE", input); |
| 525 | 525 | ||
| 526 | // TODO: why is this needed? | 526 | // TODO: why is this needed? |
| 527 | result.erase(std::remove(result.begin(), result.end(), 0x00), result.end()); | 527 | result.erase(std::remove(result.begin(), result.end(), 0x00), result.end()); |
| 528 | return result; | 528 | return result; |
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | #endif | 531 | #endif |
diff --git a/src/common/src/string_util.h b/src/common/src/string_util.h index 31eaeb246..fcbae4715 100644 --- a/src/common/src/string_util.h +++ b/src/common/src/string_util.h | |||
| @@ -21,10 +21,10 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar | |||
| 21 | template<size_t Count> | 21 | template<size_t Count> |
| 22 | inline void CharArrayFromFormat(char (& out)[Count], const char* format, ...) | 22 | inline void CharArrayFromFormat(char (& out)[Count], const char* format, ...) |
| 23 | { | 23 | { |
| 24 | va_list args; | 24 | va_list args; |
| 25 | va_start(args, format); | 25 | va_start(args, format); |
| 26 | CharArrayFromFormatV(out, Count, format, args); | 26 | CharArrayFromFormatV(out, Count, format, args); |
| 27 | va_end(args); | 27 | va_end(args); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | // Good | 30 | // Good |
| @@ -37,15 +37,15 @@ std::string StripQuotes(const std::string &s); | |||
| 37 | template <typename I> | 37 | template <typename I> |
| 38 | std::string ThousandSeparate(I value, int spaces = 0) | 38 | std::string ThousandSeparate(I value, int spaces = 0) |
| 39 | { | 39 | { |
| 40 | std::ostringstream oss; | 40 | std::ostringstream oss; |
| 41 | 41 | ||
| 42 | // std::locale("") seems to be broken on many platforms | 42 | // std::locale("") seems to be broken on many platforms |
| 43 | #if defined _WIN32 || (defined __linux__ && !defined __clang__) | 43 | #if defined _WIN32 || (defined __linux__ && !defined __clang__) |
| 44 | oss.imbue(std::locale("")); | 44 | oss.imbue(std::locale("")); |
| 45 | #endif | 45 | #endif |
| 46 | oss << std::setw(spaces) << value; | 46 | oss << std::setw(spaces) << value; |
| 47 | 47 | ||
| 48 | return oss.str(); | 48 | return oss.str(); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | std::string StringFromInt(int value); | 51 | std::string StringFromInt(int value); |
| @@ -57,16 +57,16 @@ bool TryParse(const std::string &str, u32 *output); | |||
| 57 | template <typename N> | 57 | template <typename N> |
| 58 | static bool TryParse(const std::string &str, N *const output) | 58 | static bool TryParse(const std::string &str, N *const output) |
| 59 | { | 59 | { |
| 60 | std::istringstream iss(str); | 60 | std::istringstream iss(str); |
| 61 | 61 | ||
| 62 | N tmp = 0; | 62 | N tmp = 0; |
| 63 | if (iss >> tmp) | 63 | if (iss >> tmp) |
| 64 | { | 64 | { |
| 65 | *output = tmp; | 65 | *output = tmp; |
| 66 | return true; | 66 | return true; |
| 67 | } | 67 | } |
| 68 | else | 68 | else |
| 69 | return false; | 69 | return false; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | // TODO: kill this | 72 | // TODO: kill this |
diff --git a/src/common/src/swap.h b/src/common/src/swap.h index b937f9ed1..d07d9fcc5 100644 --- a/src/common/src/swap.h +++ b/src/common/src/swap.h | |||
| @@ -63,426 +63,426 @@ | |||
| 63 | 63 | ||
| 64 | template <typename T, typename F> | 64 | template <typename T, typename F> |
| 65 | struct swap_struct_t { | 65 | struct swap_struct_t { |
| 66 | typedef swap_struct_t<T, F> swapped_t; | 66 | typedef swap_struct_t<T, F> swapped_t; |
| 67 | 67 | ||
| 68 | protected: | 68 | protected: |
| 69 | T value; | 69 | T value; |
| 70 | 70 | ||
| 71 | static T swap(T v) { | 71 | static T swap(T v) { |
| 72 | return F::swap(v); | 72 | return F::swap(v); |
| 73 | } | 73 | } |
| 74 | public: | 74 | public: |
| 75 | T const swap() const { | 75 | T const swap() const { |
| 76 | return swap(value); | 76 | return swap(value); |
| 77 | 77 | ||
| 78 | } | 78 | } |
| 79 | swap_struct_t() : value((T)0) {} | 79 | swap_struct_t() : value((T)0) {} |
| 80 | swap_struct_t(const T &v): value(swap(v)) {} | 80 | swap_struct_t(const T &v): value(swap(v)) {} |
| 81 | 81 | ||
| 82 | template <typename S> | 82 | template <typename S> |
| 83 | swapped_t& operator=(const S &source) { | 83 | swapped_t& operator=(const S &source) { |
| 84 | value = swap((T)source); | 84 | value = swap((T)source); |
| 85 | return *this; | 85 | return *this; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | operator long() const { return (long)swap(); } | 88 | operator long() const { return (long)swap(); } |
| 89 | operator s8() const { return (s8)swap(); } | 89 | operator s8() const { return (s8)swap(); } |
| 90 | operator u8() const { return (u8)swap(); } | 90 | operator u8() const { return (u8)swap(); } |
| 91 | operator s16() const { return (s16)swap(); } | 91 | operator s16() const { return (s16)swap(); } |
| 92 | operator u16() const { return (u16)swap(); } | 92 | operator u16() const { return (u16)swap(); } |
| 93 | operator s32() const { return (s32)swap(); } | 93 | operator s32() const { return (s32)swap(); } |
| 94 | operator u32() const { return (u32)swap(); } | 94 | operator u32() const { return (u32)swap(); } |
| 95 | operator s64() const { return (s64)swap(); } | 95 | operator s64() const { return (s64)swap(); } |
| 96 | operator u64() const { return (u64)swap(); } | 96 | operator u64() const { return (u64)swap(); } |
| 97 | operator float() const { return (float)swap(); } | 97 | operator float() const { return (float)swap(); } |
| 98 | operator double() const { return (double)swap(); } | 98 | operator double() const { return (double)swap(); } |
| 99 | 99 | ||
| 100 | // +v | 100 | // +v |
| 101 | swapped_t operator +() const { | 101 | swapped_t operator +() const { |
| 102 | return +swap(); | 102 | return +swap(); |
| 103 | } | 103 | } |
| 104 | // -v | 104 | // -v |
| 105 | swapped_t operator -() const { | 105 | swapped_t operator -() const { |
| 106 | return -swap(); | 106 | return -swap(); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | // v / 5 | 109 | // v / 5 |
| 110 | swapped_t operator/(const swapped_t &i) const { | 110 | swapped_t operator/(const swapped_t &i) const { |
| 111 | return swap() / i.swap(); | 111 | return swap() / i.swap(); |
| 112 | } | 112 | } |
| 113 | template <typename S> | 113 | template <typename S> |
| 114 | swapped_t operator/(const S &i) const { | 114 | swapped_t operator/(const S &i) const { |
| 115 | return swap() / i; | 115 | return swap() / i; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | // v * 5 | 118 | // v * 5 |
| 119 | swapped_t operator*(const swapped_t &i) const { | 119 | swapped_t operator*(const swapped_t &i) const { |
| 120 | return swap() * i.swap(); | 120 | return swap() * i.swap(); |
| 121 | } | 121 | } |
| 122 | template <typename S> | 122 | template <typename S> |
| 123 | swapped_t operator*(const S &i) const { | 123 | swapped_t operator*(const S &i) const { |
| 124 | return swap() * i; | 124 | return swap() * i; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | // v + 5 | 127 | // v + 5 |
| 128 | swapped_t operator+(const swapped_t &i) const { | 128 | swapped_t operator+(const swapped_t &i) const { |
| 129 | return swap() + i.swap(); | 129 | return swap() + i.swap(); |
| 130 | } | 130 | } |
| 131 | template <typename S> | 131 | template <typename S> |
| 132 | swapped_t operator+(const S &i) const { | 132 | swapped_t operator+(const S &i) const { |
| 133 | return swap() + (T)i; | 133 | return swap() + (T)i; |
| 134 | } | 134 | } |
| 135 | // v - 5 | 135 | // v - 5 |
| 136 | swapped_t operator-(const swapped_t &i) const { | 136 | swapped_t operator-(const swapped_t &i) const { |
| 137 | return swap() - i.swap(); | 137 | return swap() - i.swap(); |
| 138 | } | 138 | } |
| 139 | template <typename S> | 139 | template <typename S> |
| 140 | swapped_t operator-(const S &i) const { | 140 | swapped_t operator-(const S &i) const { |
| 141 | return swap() - (T)i; | 141 | return swap() - (T)i; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | // v += 5 | 144 | // v += 5 |
| 145 | swapped_t& operator+=(const swapped_t &i) { | 145 | swapped_t& operator+=(const swapped_t &i) { |
| 146 | value = swap(swap() + i.swap()); | 146 | value = swap(swap() + i.swap()); |
| 147 | return *this; | 147 | return *this; |
| 148 | } | 148 | } |
| 149 | template <typename S> | 149 | template <typename S> |
| 150 | swapped_t& operator+=(const S &i) { | 150 | swapped_t& operator+=(const S &i) { |
| 151 | value = swap(swap() + (T)i); | 151 | value = swap(swap() + (T)i); |
| 152 | return *this; | 152 | return *this; |
| 153 | } | 153 | } |
| 154 | // v -= 5 | 154 | // v -= 5 |
| 155 | swapped_t& operator-=(const swapped_t &i) { | 155 | swapped_t& operator-=(const swapped_t &i) { |
| 156 | value = swap(swap() - i.swap()); | 156 | value = swap(swap() - i.swap()); |
| 157 | return *this; | 157 | return *this; |
| 158 | } | 158 | } |
| 159 | template <typename S> | 159 | template <typename S> |
| 160 | swapped_t& operator-=(const S &i) { | 160 | swapped_t& operator-=(const S &i) { |
| 161 | value = swap(swap() - (T)i); | 161 | value = swap(swap() - (T)i); |
| 162 | return *this; | 162 | return *this; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | // ++v | 165 | // ++v |
| 166 | swapped_t& operator++() { | 166 | swapped_t& operator++() { |
| 167 | value = swap(swap()+1); | 167 | value = swap(swap()+1); |
| 168 | return *this; | 168 | return *this; |
| 169 | } | 169 | } |
| 170 | // --v | 170 | // --v |
| 171 | swapped_t& operator--() { | 171 | swapped_t& operator--() { |
| 172 | value = swap(swap()-1); | 172 | value = swap(swap()-1); |
| 173 | return *this; | 173 | return *this; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | // v++ | 176 | // v++ |
| 177 | swapped_t operator++(int) { | 177 | swapped_t operator++(int) { |
| 178 | swapped_t old = *this; | 178 | swapped_t old = *this; |
| 179 | value = swap(swap()+1); | 179 | value = swap(swap()+1); |
| 180 | return old; | 180 | return old; |
| 181 | } | 181 | } |
| 182 | // v-- | 182 | // v-- |
| 183 | swapped_t operator--(int) { | 183 | swapped_t operator--(int) { |
| 184 | swapped_t old = *this; | 184 | swapped_t old = *this; |
| 185 | value = swap(swap()-1); | 185 | value = swap(swap()-1); |
| 186 | return old; | 186 | return old; |
| 187 | } | 187 | } |
| 188 | // Comparaison | 188 | // Comparaison |
| 189 | // v == i | 189 | // v == i |
| 190 | bool operator==(const swapped_t &i) const { | 190 | bool operator==(const swapped_t &i) const { |
| 191 | return swap() == i.swap(); | 191 | return swap() == i.swap(); |
| 192 | } | 192 | } |
| 193 | template <typename S> | 193 | template <typename S> |
| 194 | bool operator==(const S &i) const { | 194 | bool operator==(const S &i) const { |
| 195 | return swap() == i; | 195 | return swap() == i; |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | // v != i | 198 | // v != i |
| 199 | bool operator!=(const swapped_t &i) const { | 199 | bool operator!=(const swapped_t &i) const { |
| 200 | return swap() != i.swap(); | 200 | return swap() != i.swap(); |
| 201 | } | 201 | } |
| 202 | template <typename S> | 202 | template <typename S> |
| 203 | bool operator!=(const S &i) const { | 203 | bool operator!=(const S &i) const { |
| 204 | return swap() != i; | 204 | return swap() != i; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | // v > i | 207 | // v > i |
| 208 | bool operator>(const swapped_t &i) const { | 208 | bool operator>(const swapped_t &i) const { |
| 209 | return swap() > i.swap(); | 209 | return swap() > i.swap(); |
| 210 | } | 210 | } |
| 211 | template <typename S> | 211 | template <typename S> |
| 212 | bool operator>(const S &i) const { | 212 | bool operator>(const S &i) const { |
| 213 | return swap() > i; | 213 | return swap() > i; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | // v < i | 216 | // v < i |
| 217 | bool operator<(const swapped_t &i) const { | 217 | bool operator<(const swapped_t &i) const { |
| 218 | return swap() < i.swap(); | 218 | return swap() < i.swap(); |
| 219 | } | 219 | } |
| 220 | template <typename S> | 220 | template <typename S> |
| 221 | bool operator<(const S &i) const { | 221 | bool operator<(const S &i) const { |
| 222 | return swap() < i; | 222 | return swap() < i; |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | // v >= i | 225 | // v >= i |
| 226 | bool operator>=(const swapped_t &i) const { | 226 | bool operator>=(const swapped_t &i) const { |
| 227 | return swap() >= i.swap(); | 227 | return swap() >= i.swap(); |
| 228 | } | 228 | } |
| 229 | template <typename S> | 229 | template <typename S> |
| 230 | bool operator>=(const S &i) const { | 230 | bool operator>=(const S &i) const { |
| 231 | return swap() >= i; | 231 | return swap() >= i; |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | // v <= i | 234 | // v <= i |
| 235 | bool operator<=(const swapped_t &i) const { | 235 | bool operator<=(const swapped_t &i) const { |
| 236 | return swap() <= i.swap(); | 236 | return swap() <= i.swap(); |
| 237 | } | 237 | } |
| 238 | template <typename S> | 238 | template <typename S> |
| 239 | bool operator<=(const S &i) const { | 239 | bool operator<=(const S &i) const { |
| 240 | return swap() <= i; | 240 | return swap() <= i; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | // logical | 243 | // logical |
| 244 | swapped_t operator !() const { | 244 | swapped_t operator !() const { |
| 245 | return !swap(); | 245 | return !swap(); |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | // bitmath | 248 | // bitmath |
| 249 | swapped_t operator ~() const { | 249 | swapped_t operator ~() const { |
| 250 | return ~swap(); | 250 | return ~swap(); |
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | swapped_t operator &(const swapped_t &b) const { | 253 | swapped_t operator &(const swapped_t &b) const { |
| 254 | return swap() & b.swap(); | 254 | return swap() & b.swap(); |
| 255 | } | 255 | } |
| 256 | template <typename S> | 256 | template <typename S> |
| 257 | swapped_t operator &(const S &b) const { | 257 | swapped_t operator &(const S &b) const { |
| 258 | return swap() & b; | 258 | return swap() & b; |
| 259 | } | 259 | } |
| 260 | swapped_t& operator &=(const swapped_t &b) { | 260 | swapped_t& operator &=(const swapped_t &b) { |
| 261 | value = swap(swap() & b.swap()); | 261 | value = swap(swap() & b.swap()); |
| 262 | return *this; | 262 | return *this; |
| 263 | } | 263 | } |
| 264 | template <typename S> | 264 | template <typename S> |
| 265 | swapped_t& operator &=(const S b) { | 265 | swapped_t& operator &=(const S b) { |
| 266 | value = swap(swap() & b); | 266 | value = swap(swap() & b); |
| 267 | return *this; | 267 | return *this; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | swapped_t operator |(const swapped_t &b) const { | 270 | swapped_t operator |(const swapped_t &b) const { |
| 271 | return swap() | b.swap(); | 271 | return swap() | b.swap(); |
| 272 | } | 272 | } |
| 273 | template <typename S> | 273 | template <typename S> |
| 274 | swapped_t operator |(const S &b) const { | 274 | swapped_t operator |(const S &b) const { |
| 275 | return swap() | b; | 275 | return swap() | b; |
| 276 | } | 276 | } |
| 277 | swapped_t& operator |=(const swapped_t &b) { | 277 | swapped_t& operator |=(const swapped_t &b) { |
| 278 | value = swap(swap() | b.swap()); | 278 | value = swap(swap() | b.swap()); |
| 279 | return *this; | 279 | return *this; |
| 280 | } | 280 | } |
| 281 | template <typename S> | 281 | template <typename S> |
| 282 | swapped_t& operator |=(const S &b) { | 282 | swapped_t& operator |=(const S &b) { |
| 283 | value = swap(swap() | b); | 283 | value = swap(swap() | b); |
| 284 | return *this; | 284 | return *this; |
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | swapped_t operator ^(const swapped_t &b) const { | 287 | swapped_t operator ^(const swapped_t &b) const { |
| 288 | return swap() ^ b.swap(); | 288 | return swap() ^ b.swap(); |
| 289 | } | 289 | } |
| 290 | template <typename S> | 290 | template <typename S> |
| 291 | swapped_t operator ^(const S &b) const { | 291 | swapped_t operator ^(const S &b) const { |
| 292 | return swap() ^ b; | 292 | return swap() ^ b; |
| 293 | } | 293 | } |
| 294 | swapped_t& operator ^=(const swapped_t &b) { | 294 | swapped_t& operator ^=(const swapped_t &b) { |
| 295 | value = swap(swap() ^ b.swap()); | 295 | value = swap(swap() ^ b.swap()); |
| 296 | return *this; | 296 | return *this; |
| 297 | } | 297 | } |
| 298 | template <typename S> | 298 | template <typename S> |
| 299 | swapped_t& operator ^=(const S &b) { | 299 | swapped_t& operator ^=(const S &b) { |
| 300 | value = swap(swap() ^ b); | 300 | value = swap(swap() ^ b); |
| 301 | return *this; | 301 | return *this; |
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | template <typename S> | 304 | template <typename S> |
| 305 | swapped_t operator <<(const S &b) const { | 305 | swapped_t operator <<(const S &b) const { |
| 306 | return swap() << b; | 306 | return swap() << b; |
| 307 | } | 307 | } |
| 308 | template <typename S> | 308 | template <typename S> |
| 309 | swapped_t& operator <<=(const S &b) const { | 309 | swapped_t& operator <<=(const S &b) const { |
| 310 | value = swap(swap() << b); | 310 | value = swap(swap() << b); |
| 311 | return *this; | 311 | return *this; |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | template <typename S> | 314 | template <typename S> |
| 315 | swapped_t operator >>(const S &b) const { | 315 | swapped_t operator >>(const S &b) const { |
| 316 | return swap() >> b; | 316 | return swap() >> b; |
| 317 | } | 317 | } |
| 318 | template <typename S> | 318 | template <typename S> |
| 319 | swapped_t& operator >>=(const S &b) const { | 319 | swapped_t& operator >>=(const S &b) const { |
| 320 | value = swap(swap() >> b); | 320 | value = swap(swap() >> b); |
| 321 | return *this; | 321 | return *this; |
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | // Member | 324 | // Member |
| 325 | /** todo **/ | 325 | /** todo **/ |
| 326 | 326 | ||
| 327 | 327 | ||
| 328 | // Arithmetics | 328 | // Arithmetics |
| 329 | template <typename S, typename T2, typename F2> | 329 | template <typename S, typename T2, typename F2> |
| 330 | friend S operator+(const S &p, const swapped_t v); | 330 | friend S operator+(const S &p, const swapped_t v); |
| 331 | 331 | ||
| 332 | template <typename S, typename T2, typename F2> | 332 | template <typename S, typename T2, typename F2> |
| 333 | friend S operator-(const S &p, const swapped_t v); | 333 | friend S operator-(const S &p, const swapped_t v); |
| 334 | 334 | ||
| 335 | template <typename S, typename T2, typename F2> | 335 | template <typename S, typename T2, typename F2> |
| 336 | friend S operator/(const S &p, const swapped_t v); | 336 | friend S operator/(const S &p, const swapped_t v); |
| 337 | 337 | ||
| 338 | template <typename S, typename T2, typename F2> | 338 | template <typename S, typename T2, typename F2> |
| 339 | friend S operator*(const S &p, const swapped_t v); | 339 | friend S operator*(const S &p, const swapped_t v); |
| 340 | 340 | ||
| 341 | template <typename S, typename T2, typename F2> | 341 | template <typename S, typename T2, typename F2> |
| 342 | friend S operator%(const S &p, const swapped_t v); | 342 | friend S operator%(const S &p, const swapped_t v); |
| 343 | 343 | ||
| 344 | // Arithmetics + assignements | 344 | // Arithmetics + assignements |
| 345 | template <typename S, typename T2, typename F2> | 345 | template <typename S, typename T2, typename F2> |
| 346 | friend S operator+=(const S &p, const swapped_t v); | 346 | friend S operator+=(const S &p, const swapped_t v); |
| 347 | 347 | ||
| 348 | template <typename S, typename T2, typename F2> | 348 | template <typename S, typename T2, typename F2> |
| 349 | friend S operator-=(const S &p, const swapped_t v); | 349 | friend S operator-=(const S &p, const swapped_t v); |
| 350 | 350 | ||
| 351 | // Bitmath | 351 | // Bitmath |
| 352 | template <typename S, typename T2, typename F2> | 352 | template <typename S, typename T2, typename F2> |
| 353 | friend S operator&(const S &p, const swapped_t v); | 353 | friend S operator&(const S &p, const swapped_t v); |
| 354 | 354 | ||
| 355 | // Comparison | 355 | // Comparison |
| 356 | template <typename S, typename T2, typename F2> | 356 | template <typename S, typename T2, typename F2> |
| 357 | friend bool operator<(const S &p, const swapped_t v); | 357 | friend bool operator<(const S &p, const swapped_t v); |
| 358 | 358 | ||
| 359 | template <typename S, typename T2, typename F2> | 359 | template <typename S, typename T2, typename F2> |
| 360 | friend bool operator>(const S &p, const swapped_t v); | 360 | friend bool operator>(const S &p, const swapped_t v); |
| 361 | 361 | ||
| 362 | template <typename S, typename T2, typename F2> | 362 | template <typename S, typename T2, typename F2> |
| 363 | friend bool operator<=(const S &p, const swapped_t v); | 363 | friend bool operator<=(const S &p, const swapped_t v); |
| 364 | 364 | ||
| 365 | template <typename S, typename T2, typename F2> | 365 | template <typename S, typename T2, typename F2> |
| 366 | friend bool operator>=(const S &p, const swapped_t v); | 366 | friend bool operator>=(const S &p, const swapped_t v); |
| 367 | 367 | ||
| 368 | template <typename S, typename T2, typename F2> | 368 | template <typename S, typename T2, typename F2> |
| 369 | friend bool operator!=(const S &p, const swapped_t v); | 369 | friend bool operator!=(const S &p, const swapped_t v); |
| 370 | 370 | ||
| 371 | template <typename S, typename T2, typename F2> | 371 | template <typename S, typename T2, typename F2> |
| 372 | friend bool operator==(const S &p, const swapped_t v); | 372 | friend bool operator==(const S &p, const swapped_t v); |
| 373 | }; | 373 | }; |
| 374 | 374 | ||
| 375 | 375 | ||
| 376 | // Arithmetics | 376 | // Arithmetics |
| 377 | template <typename S, typename T, typename F> | 377 | template <typename S, typename T, typename F> |
| 378 | S operator+(const S &i, const swap_struct_t<T, F> v) { | 378 | S operator+(const S &i, const swap_struct_t<T, F> v) { |
| 379 | return i + v.swap(); | 379 | return i + v.swap(); |
| 380 | } | 380 | } |
| 381 | 381 | ||
| 382 | template <typename S, typename T, typename F> | 382 | template <typename S, typename T, typename F> |
| 383 | S operator-(const S &i, const swap_struct_t<T, F> v) { | 383 | S operator-(const S &i, const swap_struct_t<T, F> v) { |
| 384 | return i - v.swap(); | 384 | return i - v.swap(); |
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | template <typename S, typename T, typename F> | 387 | template <typename S, typename T, typename F> |
| 388 | S operator/(const S &i, const swap_struct_t<T, F> v) { | 388 | S operator/(const S &i, const swap_struct_t<T, F> v) { |
| 389 | return i / v.swap(); | 389 | return i / v.swap(); |
| 390 | } | 390 | } |
| 391 | 391 | ||
| 392 | template <typename S, typename T, typename F> | 392 | template <typename S, typename T, typename F> |
| 393 | S operator*(const S &i, const swap_struct_t<T, F> v) { | 393 | S operator*(const S &i, const swap_struct_t<T, F> v) { |
| 394 | return i * v.swap(); | 394 | return i * v.swap(); |
| 395 | } | 395 | } |
| 396 | 396 | ||
| 397 | template <typename S, typename T, typename F> | 397 | template <typename S, typename T, typename F> |
| 398 | S operator%(const S &i, const swap_struct_t<T, F> v) { | 398 | S operator%(const S &i, const swap_struct_t<T, F> v) { |
| 399 | return i % v.swap(); | 399 | return i % v.swap(); |
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | // Arithmetics + assignements | 402 | // Arithmetics + assignements |
| 403 | template <typename S, typename T, typename F> | 403 | template <typename S, typename T, typename F> |
| 404 | S &operator+=(S &i, const swap_struct_t<T, F> v) { | 404 | S &operator+=(S &i, const swap_struct_t<T, F> v) { |
| 405 | i += v.swap(); | 405 | i += v.swap(); |
| 406 | return i; | 406 | return i; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | template <typename S, typename T, typename F> | 409 | template <typename S, typename T, typename F> |
| 410 | S &operator-=(S &i, const swap_struct_t<T, F> v) { | 410 | S &operator-=(S &i, const swap_struct_t<T, F> v) { |
| 411 | i -= v.swap(); | 411 | i -= v.swap(); |
| 412 | return i; | 412 | return i; |
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | // Logical | 415 | // Logical |
| 416 | template <typename S, typename T, typename F> | 416 | template <typename S, typename T, typename F> |
| 417 | S operator&(const S &i, const swap_struct_t<T, F> v) { | 417 | S operator&(const S &i, const swap_struct_t<T, F> v) { |
| 418 | return i & v.swap(); | 418 | return i & v.swap(); |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | template <typename S, typename T, typename F> | 421 | template <typename S, typename T, typename F> |
| 422 | S operator&(const swap_struct_t<T, F> v, const S &i) { | 422 | S operator&(const swap_struct_t<T, F> v, const S &i) { |
| 423 | return (S)(v.swap() & i); | 423 | return (S)(v.swap() & i); |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | 426 | ||
| 427 | // Comparaison | 427 | // Comparaison |
| 428 | template <typename S, typename T, typename F> | 428 | template <typename S, typename T, typename F> |
| 429 | bool operator<(const S &p, const swap_struct_t<T, F> v) { | 429 | bool operator<(const S &p, const swap_struct_t<T, F> v) { |
| 430 | return p < v.swap(); | 430 | return p < v.swap(); |
| 431 | } | 431 | } |
| 432 | template <typename S, typename T, typename F> | 432 | template <typename S, typename T, typename F> |
| 433 | bool operator>(const S &p, const swap_struct_t<T, F> v) { | 433 | bool operator>(const S &p, const swap_struct_t<T, F> v) { |
| 434 | return p > v.swap(); | 434 | return p > v.swap(); |
| 435 | } | 435 | } |
| 436 | template <typename S, typename T, typename F> | 436 | template <typename S, typename T, typename F> |
| 437 | bool operator<=(const S &p, const swap_struct_t<T, F> v) { | 437 | bool operator<=(const S &p, const swap_struct_t<T, F> v) { |
| 438 | return p <= v.swap(); | 438 | return p <= v.swap(); |
| 439 | } | 439 | } |
| 440 | template <typename S, typename T, typename F> | 440 | template <typename S, typename T, typename F> |
| 441 | bool operator>=(const S &p, const swap_struct_t<T, F> v) { | 441 | bool operator>=(const S &p, const swap_struct_t<T, F> v) { |
| 442 | return p >= v.swap(); | 442 | return p >= v.swap(); |
| 443 | } | 443 | } |
| 444 | template <typename S, typename T, typename F> | 444 | template <typename S, typename T, typename F> |
| 445 | bool operator!=(const S &p, const swap_struct_t<T, F> v) { | 445 | bool operator!=(const S &p, const swap_struct_t<T, F> v) { |
| 446 | return p != v.swap(); | 446 | return p != v.swap(); |
| 447 | } | 447 | } |
| 448 | template <typename S, typename T, typename F> | 448 | template <typename S, typename T, typename F> |
| 449 | bool operator==(const S &p, const swap_struct_t<T, F> v) { | 449 | bool operator==(const S &p, const swap_struct_t<T, F> v) { |
| 450 | return p == v.swap(); | 450 | return p == v.swap(); |
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | template <typename T> | 453 | template <typename T> |
| 454 | struct swap_64_t { | 454 | struct swap_64_t { |
| 455 | static T swap(T x) { | 455 | static T swap(T x) { |
| 456 | return (T)bswap64(*(u64 *)&x); | 456 | return (T)bswap64(*(u64 *)&x); |
| 457 | } | 457 | } |
| 458 | }; | 458 | }; |
| 459 | 459 | ||
| 460 | template <typename T> | 460 | template <typename T> |
| 461 | struct swap_32_t { | 461 | struct swap_32_t { |
| 462 | static T swap(T x) { | 462 | static T swap(T x) { |
| 463 | return (T)bswap32(*(u32 *)&x); | 463 | return (T)bswap32(*(u32 *)&x); |
| 464 | } | 464 | } |
| 465 | }; | 465 | }; |
| 466 | 466 | ||
| 467 | template <typename T> | 467 | template <typename T> |
| 468 | struct swap_16_t { | 468 | struct swap_16_t { |
| 469 | static T swap(T x) { | 469 | static T swap(T x) { |
| 470 | return (T)bswap16(*(u16 *)&x); | 470 | return (T)bswap16(*(u16 *)&x); |
| 471 | } | 471 | } |
| 472 | }; | 472 | }; |
| 473 | 473 | ||
| 474 | template <typename T> | 474 | template <typename T> |
| 475 | struct swap_float_t { | 475 | struct swap_float_t { |
| 476 | static T swap(T x) { | 476 | static T swap(T x) { |
| 477 | return (T)bswapf(*(float *)&x); | 477 | return (T)bswapf(*(float *)&x); |
| 478 | } | 478 | } |
| 479 | }; | 479 | }; |
| 480 | 480 | ||
| 481 | template <typename T> | 481 | template <typename T> |
| 482 | struct swap_double_t { | 482 | struct swap_double_t { |
| 483 | static T swap(T x) { | 483 | static T swap(T x) { |
| 484 | return (T)bswapd(*(double *)&x); | 484 | return (T)bswapd(*(double *)&x); |
| 485 | } | 485 | } |
| 486 | }; | 486 | }; |
| 487 | 487 | ||
| 488 | #if COMMON_LITTLE_ENDIAN | 488 | #if COMMON_LITTLE_ENDIAN |
diff --git a/src/common/src/thread.cpp b/src/common/src/thread.cpp index e75dfffeb..27dbf3f93 100644 --- a/src/common/src/thread.cpp +++ b/src/common/src/thread.cpp | |||
| @@ -21,110 +21,110 @@ namespace Common | |||
| 21 | int CurrentThreadId() | 21 | int CurrentThreadId() |
| 22 | { | 22 | { |
| 23 | #ifdef _WIN32 | 23 | #ifdef _WIN32 |
| 24 | return GetCurrentThreadId(); | 24 | return GetCurrentThreadId(); |
| 25 | #elif defined __APPLE__ | 25 | #elif defined __APPLE__ |
| 26 | return mach_thread_self(); | 26 | return mach_thread_self(); |
| 27 | #else | 27 | #else |
| 28 | return 0; | 28 | return 0; |
| 29 | #endif | 29 | #endif |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | #ifdef _WIN32 | 32 | #ifdef _WIN32 |
| 33 | 33 | ||
| 34 | void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) | 34 | void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) |
| 35 | { | 35 | { |
| 36 | SetThreadAffinityMask(thread, mask); | 36 | SetThreadAffinityMask(thread, mask); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void SetCurrentThreadAffinity(u32 mask) | 39 | void SetCurrentThreadAffinity(u32 mask) |
| 40 | { | 40 | { |
| 41 | SetThreadAffinityMask(GetCurrentThread(), mask); | 41 | SetThreadAffinityMask(GetCurrentThread(), mask); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | // Supporting functions | 44 | // Supporting functions |
| 45 | void SleepCurrentThread(int ms) | 45 | void SleepCurrentThread(int ms) |
| 46 | { | 46 | { |
| 47 | Sleep(ms); | 47 | Sleep(ms); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | void SwitchCurrentThread() | 50 | void SwitchCurrentThread() |
| 51 | { | 51 | { |
| 52 | SwitchToThread(); | 52 | SwitchToThread(); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | // Sets the debugger-visible name of the current thread. | 55 | // Sets the debugger-visible name of the current thread. |
| 56 | // Uses undocumented (actually, it is now documented) trick. | 56 | // Uses undocumented (actually, it is now documented) trick. |
| 57 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsdebug/html/vxtsksettingthreadname.asp | 57 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsdebug/html/vxtsksettingthreadname.asp |
| 58 | 58 | ||
| 59 | // This is implemented much nicer in upcoming msvc++, see: | 59 | // This is implemented much nicer in upcoming msvc++, see: |
| 60 | // http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.100).aspx | 60 | // http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.100).aspx |
| 61 | void SetCurrentThreadName(const char* szThreadName) | 61 | void SetCurrentThreadName(const char* szThreadName) |
| 62 | { | 62 | { |
| 63 | static const DWORD MS_VC_EXCEPTION = 0x406D1388; | 63 | static const DWORD MS_VC_EXCEPTION = 0x406D1388; |
| 64 | 64 | ||
| 65 | #pragma pack(push,8) | 65 | #pragma pack(push,8) |
| 66 | struct THREADNAME_INFO | 66 | struct THREADNAME_INFO |
| 67 | { | 67 | { |
| 68 | DWORD dwType; // must be 0x1000 | 68 | DWORD dwType; // must be 0x1000 |
| 69 | LPCSTR szName; // pointer to name (in user addr space) | 69 | LPCSTR szName; // pointer to name (in user addr space) |
| 70 | DWORD dwThreadID; // thread ID (-1=caller thread) | 70 | DWORD dwThreadID; // thread ID (-1=caller thread) |
| 71 | DWORD dwFlags; // reserved for future use, must be zero | 71 | DWORD dwFlags; // reserved for future use, must be zero |
| 72 | } info; | 72 | } info; |
| 73 | #pragma pack(pop) | 73 | #pragma pack(pop) |
| 74 | 74 | ||
| 75 | info.dwType = 0x1000; | 75 | info.dwType = 0x1000; |
| 76 | info.szName = szThreadName; | 76 | info.szName = szThreadName; |
| 77 | info.dwThreadID = -1; //dwThreadID; | 77 | info.dwThreadID = -1; //dwThreadID; |
| 78 | info.dwFlags = 0; | 78 | info.dwFlags = 0; |
| 79 | 79 | ||
| 80 | __try | 80 | __try |
| 81 | { | 81 | { |
| 82 | RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info); | 82 | RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info); |
| 83 | } | 83 | } |
| 84 | __except(EXCEPTION_CONTINUE_EXECUTION) | 84 | __except(EXCEPTION_CONTINUE_EXECUTION) |
| 85 | {} | 85 | {} |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | #else // !WIN32, so must be POSIX threads | 88 | #else // !WIN32, so must be POSIX threads |
| 89 | 89 | ||
| 90 | void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) | 90 | void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) |
| 91 | { | 91 | { |
| 92 | #ifdef __APPLE__ | 92 | #ifdef __APPLE__ |
| 93 | thread_policy_set(pthread_mach_thread_np(thread), | 93 | thread_policy_set(pthread_mach_thread_np(thread), |
| 94 | THREAD_AFFINITY_POLICY, (integer_t *)&mask, 1); | 94 | THREAD_AFFINITY_POLICY, (integer_t *)&mask, 1); |
| 95 | #elif (defined __linux__ || defined BSD4_4) && !(defined ANDROID) | 95 | #elif (defined __linux__ || defined BSD4_4) && !(defined ANDROID) |
| 96 | cpu_set_t cpu_set; | 96 | cpu_set_t cpu_set; |
| 97 | CPU_ZERO(&cpu_set); | 97 | CPU_ZERO(&cpu_set); |
| 98 | 98 | ||
| 99 | for (int i = 0; i != sizeof(mask) * 8; ++i) | 99 | for (int i = 0; i != sizeof(mask) * 8; ++i) |
| 100 | if ((mask >> i) & 1) | 100 | if ((mask >> i) & 1) |
| 101 | CPU_SET(i, &cpu_set); | 101 | CPU_SET(i, &cpu_set); |
| 102 | 102 | ||
| 103 | pthread_setaffinity_np(thread, sizeof(cpu_set), &cpu_set); | 103 | pthread_setaffinity_np(thread, sizeof(cpu_set), &cpu_set); |
| 104 | #endif | 104 | #endif |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | void SetCurrentThreadAffinity(u32 mask) | 107 | void SetCurrentThreadAffinity(u32 mask) |
| 108 | { | 108 | { |
| 109 | SetThreadAffinity(pthread_self(), mask); | 109 | SetThreadAffinity(pthread_self(), mask); |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | void SleepCurrentThread(int ms) | 112 | void SleepCurrentThread(int ms) |
| 113 | { | 113 | { |
| 114 | usleep(1000 * ms); | 114 | usleep(1000 * ms); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | void SwitchCurrentThread() | 117 | void SwitchCurrentThread() |
| 118 | { | 118 | { |
| 119 | usleep(1000 * 1); | 119 | usleep(1000 * 1); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | void SetCurrentThreadName(const char* szThreadName) | 122 | void SetCurrentThreadName(const char* szThreadName) |
| 123 | { | 123 | { |
| 124 | #ifdef __APPLE__ | 124 | #ifdef __APPLE__ |
| 125 | pthread_setname_np(szThreadName); | 125 | pthread_setname_np(szThreadName); |
| 126 | #else | 126 | #else |
| 127 | pthread_setname_np(pthread_self(), szThreadName); | 127 | pthread_setname_np(pthread_self(), szThreadName); |
| 128 | #endif | 128 | #endif |
| 129 | } | 129 | } |
| 130 | 130 | ||
diff --git a/src/common/src/thread.h b/src/common/src/thread.h index 3178c40f7..6384a44a1 100644 --- a/src/common/src/thread.h +++ b/src/common/src/thread.h | |||
| @@ -32,125 +32,125 @@ int CurrentThreadId(); | |||
| 32 | 32 | ||
| 33 | void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask); | 33 | void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask); |
| 34 | void SetCurrentThreadAffinity(u32 mask); | 34 | void SetCurrentThreadAffinity(u32 mask); |
| 35 | 35 | ||
| 36 | class Event | 36 | class Event |
| 37 | { | 37 | { |
| 38 | public: | 38 | public: |
| 39 | Event() | 39 | Event() |
| 40 | : is_set(false) | 40 | : is_set(false) |
| 41 | {}; | 41 | {}; |
| 42 | 42 | ||
| 43 | void Set() | 43 | void Set() |
| 44 | { | 44 | { |
| 45 | std::lock_guard<std::mutex> lk(m_mutex); | 45 | std::lock_guard<std::mutex> lk(m_mutex); |
| 46 | if (!is_set) | 46 | if (!is_set) |
| 47 | { | 47 | { |
| 48 | is_set = true; | 48 | is_set = true; |
| 49 | m_condvar.notify_one(); | 49 | m_condvar.notify_one(); |
| 50 | } | 50 | } |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | void Wait() | 53 | void Wait() |
| 54 | { | 54 | { |
| 55 | std::unique_lock<std::mutex> lk(m_mutex); | 55 | std::unique_lock<std::mutex> lk(m_mutex); |
| 56 | m_condvar.wait(lk, IsSet(this)); | 56 | m_condvar.wait(lk, IsSet(this)); |
| 57 | is_set = false; | 57 | is_set = false; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | void Reset() | 60 | void Reset() |
| 61 | { | 61 | { |
| 62 | std::unique_lock<std::mutex> lk(m_mutex); | 62 | std::unique_lock<std::mutex> lk(m_mutex); |
| 63 | // no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration | 63 | // no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration |
| 64 | is_set = false; | 64 | is_set = false; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | private: | 67 | private: |
| 68 | class IsSet | 68 | class IsSet |
| 69 | { | 69 | { |
| 70 | public: | 70 | public: |
| 71 | IsSet(const Event* ev) | 71 | IsSet(const Event* ev) |
| 72 | : m_event(ev) | 72 | : m_event(ev) |
| 73 | {} | 73 | {} |
| 74 | 74 | ||
| 75 | bool operator()() | 75 | bool operator()() |
| 76 | { | 76 | { |
| 77 | return m_event->is_set; | 77 | return m_event->is_set; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | private: | 80 | private: |
| 81 | const Event* const m_event; | 81 | const Event* const m_event; |
| 82 | }; | 82 | }; |
| 83 | 83 | ||
| 84 | volatile bool is_set; | 84 | volatile bool is_set; |
| 85 | std::condition_variable m_condvar; | 85 | std::condition_variable m_condvar; |
| 86 | std::mutex m_mutex; | 86 | std::mutex m_mutex; |
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | // TODO: doesn't work on windows with (count > 2) | 89 | // TODO: doesn't work on windows with (count > 2) |
| 90 | class Barrier | 90 | class Barrier |
| 91 | { | 91 | { |
| 92 | public: | 92 | public: |
| 93 | Barrier(size_t count) | 93 | Barrier(size_t count) |
| 94 | : m_count(count), m_waiting(0) | 94 | : m_count(count), m_waiting(0) |
| 95 | {} | 95 | {} |
| 96 | 96 | ||
| 97 | // block until "count" threads call Sync() | 97 | // block until "count" threads call Sync() |
| 98 | bool Sync() | 98 | bool Sync() |
| 99 | { | 99 | { |
| 100 | std::unique_lock<std::mutex> lk(m_mutex); | 100 | std::unique_lock<std::mutex> lk(m_mutex); |
| 101 | 101 | ||
| 102 | // TODO: broken when next round of Sync()s | 102 | // TODO: broken when next round of Sync()s |
| 103 | // is entered before all waiting threads return from the notify_all | 103 | // is entered before all waiting threads return from the notify_all |
| 104 | 104 | ||
| 105 | if (m_count == ++m_waiting) | 105 | if (m_count == ++m_waiting) |
| 106 | { | 106 | { |
| 107 | m_waiting = 0; | 107 | m_waiting = 0; |
| 108 | m_condvar.notify_all(); | 108 | m_condvar.notify_all(); |
| 109 | return true; | 109 | return true; |
| 110 | } | 110 | } |
| 111 | else | 111 | else |
| 112 | { | 112 | { |
| 113 | m_condvar.wait(lk, IsDoneWating(this)); | 113 | m_condvar.wait(lk, IsDoneWating(this)); |
| 114 | return false; | 114 | return false; |
| 115 | } | 115 | } |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | private: | 118 | private: |
| 119 | class IsDoneWating | 119 | class IsDoneWating |
| 120 | { | 120 | { |
| 121 | public: | 121 | public: |
| 122 | IsDoneWating(const Barrier* bar) | 122 | IsDoneWating(const Barrier* bar) |
| 123 | : m_bar(bar) | 123 | : m_bar(bar) |
| 124 | {} | 124 | {} |
| 125 | 125 | ||
| 126 | bool operator()() | 126 | bool operator()() |
| 127 | { | 127 | { |
| 128 | return (0 == m_bar->m_waiting); | 128 | return (0 == m_bar->m_waiting); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | private: | 131 | private: |
| 132 | const Barrier* const m_bar; | 132 | const Barrier* const m_bar; |
| 133 | }; | 133 | }; |
| 134 | 134 | ||
| 135 | std::condition_variable m_condvar; | 135 | std::condition_variable m_condvar; |
| 136 | std::mutex m_mutex; | 136 | std::mutex m_mutex; |
| 137 | const size_t m_count; | 137 | const size_t m_count; |
| 138 | volatile size_t m_waiting; | 138 | volatile size_t m_waiting; |
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | void SleepCurrentThread(int ms); | 141 | void SleepCurrentThread(int ms); |
| 142 | void SwitchCurrentThread(); // On Linux, this is equal to sleep 1ms | 142 | void SwitchCurrentThread(); // On Linux, this is equal to sleep 1ms |
| 143 | 143 | ||
| 144 | // Use this function during a spin-wait to make the current thread | 144 | // Use this function during a spin-wait to make the current thread |
| 145 | // relax while another thread is working. This may be more efficient | 145 | // relax while another thread is working. This may be more efficient |
| 146 | // than using events because event functions use kernel calls. | 146 | // than using events because event functions use kernel calls. |
| 147 | inline void YieldCPU() | 147 | inline void YieldCPU() |
| 148 | { | 148 | { |
| 149 | std::this_thread::yield(); | 149 | std::this_thread::yield(); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | void SetCurrentThreadName(const char *name); | 152 | void SetCurrentThreadName(const char *name); |
| 153 | 153 | ||
| 154 | } // namespace Common | 154 | } // namespace Common |
| 155 | 155 | ||
| 156 | #endif // _THREAD_H_ | 156 | #endif // _THREAD_H_ |
diff --git a/src/common/src/thunk.h b/src/common/src/thunk.h index 4b64a9b0e..c9e6fd39f 100644 --- a/src/common/src/thunk.h +++ b/src/common/src/thunk.h | |||
| @@ -24,23 +24,23 @@ | |||
| 24 | 24 | ||
| 25 | class ThunkManager : public Gen::XCodeBlock | 25 | class ThunkManager : public Gen::XCodeBlock |
| 26 | { | 26 | { |
| 27 | std::map<void *, const u8 *> thunks; | 27 | std::map<void *, const u8 *> thunks; |
| 28 | 28 | ||
| 29 | const u8 *save_regs; | 29 | const u8 *save_regs; |
| 30 | const u8 *load_regs; | 30 | const u8 *load_regs; |
| 31 | 31 | ||
| 32 | public: | 32 | public: |
| 33 | ThunkManager() { | 33 | ThunkManager() { |
| 34 | Init(); | 34 | Init(); |
| 35 | } | 35 | } |
| 36 | ~ThunkManager() { | 36 | ~ThunkManager() { |
| 37 | Shutdown(); | 37 | Shutdown(); |
| 38 | } | 38 | } |
| 39 | void *ProtectFunction(void *function, int num_params); | 39 | void *ProtectFunction(void *function, int num_params); |
| 40 | private: | 40 | private: |
| 41 | void Init(); | 41 | void Init(); |
| 42 | void Shutdown(); | 42 | void Shutdown(); |
| 43 | void Reset(); | 43 | void Reset(); |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | #endif // _THUNK_H_ | 46 | #endif // _THUNK_H_ |
diff --git a/src/common/src/timer.cpp b/src/common/src/timer.cpp index 0300133c5..90604292e 100644 --- a/src/common/src/timer.cpp +++ b/src/common/src/timer.cpp | |||
| @@ -22,11 +22,11 @@ namespace Common | |||
| 22 | u32 Timer::GetTimeMs() | 22 | u32 Timer::GetTimeMs() |
| 23 | { | 23 | { |
| 24 | #ifdef _WIN32 | 24 | #ifdef _WIN32 |
| 25 | return timeGetTime(); | 25 | return timeGetTime(); |
| 26 | #else | 26 | #else |
| 27 | struct timeval t; | 27 | struct timeval t; |
| 28 | (void)gettimeofday(&t, NULL); | 28 | (void)gettimeofday(&t, NULL); |
| 29 | return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); | 29 | return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); |
| 30 | #endif | 30 | #endif |
| 31 | } | 31 | } |
| 32 | 32 | ||
| @@ -36,31 +36,31 @@ u32 Timer::GetTimeMs() | |||
| 36 | 36 | ||
| 37 | // Set initial values for the class | 37 | // Set initial values for the class |
| 38 | Timer::Timer() | 38 | Timer::Timer() |
| 39 | : m_LastTime(0), m_StartTime(0), m_Running(false) | 39 | : m_LastTime(0), m_StartTime(0), m_Running(false) |
| 40 | { | 40 | { |
| 41 | Update(); | 41 | Update(); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | // Write the starting time | 44 | // Write the starting time |
| 45 | void Timer::Start() | 45 | void Timer::Start() |
| 46 | { | 46 | { |
| 47 | m_StartTime = GetTimeMs(); | 47 | m_StartTime = GetTimeMs(); |
| 48 | m_Running = true; | 48 | m_Running = true; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | // Stop the timer | 51 | // Stop the timer |
| 52 | void Timer::Stop() | 52 | void Timer::Stop() |
| 53 | { | 53 | { |
| 54 | // Write the final time | 54 | // Write the final time |
| 55 | m_LastTime = GetTimeMs(); | 55 | m_LastTime = GetTimeMs(); |
| 56 | m_Running = false; | 56 | m_Running = false; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | // Update the last time variable | 59 | // Update the last time variable |
| 60 | void Timer::Update() | 60 | void Timer::Update() |
| 61 | { | 61 | { |
| 62 | m_LastTime = GetTimeMs(); | 62 | m_LastTime = GetTimeMs(); |
| 63 | //TODO(ector) - QPF | 63 | //TODO(ector) - QPF |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | // ------------------------------------- | 66 | // ------------------------------------- |
| @@ -70,125 +70,125 @@ void Timer::Update() | |||
| 70 | // Get the number of milliseconds since the last Update() | 70 | // Get the number of milliseconds since the last Update() |
| 71 | u64 Timer::GetTimeDifference() | 71 | u64 Timer::GetTimeDifference() |
| 72 | { | 72 | { |
| 73 | return GetTimeMs() - m_LastTime; | 73 | return GetTimeMs() - m_LastTime; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | // Add the time difference since the last Update() to the starting time. | 76 | // Add the time difference since the last Update() to the starting time. |
| 77 | // This is used to compensate for a paused game. | 77 | // This is used to compensate for a paused game. |
| 78 | void Timer::AddTimeDifference() | 78 | void Timer::AddTimeDifference() |
| 79 | { | 79 | { |
| 80 | m_StartTime += GetTimeDifference(); | 80 | m_StartTime += GetTimeDifference(); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | // Get the time elapsed since the Start() | 83 | // Get the time elapsed since the Start() |
| 84 | u64 Timer::GetTimeElapsed() | 84 | u64 Timer::GetTimeElapsed() |
| 85 | { | 85 | { |
| 86 | // If we have not started yet, return 1 (because then I don't | 86 | // If we have not started yet, return 1 (because then I don't |
| 87 | // have to change the FPS calculation in CoreRerecording.cpp . | 87 | // have to change the FPS calculation in CoreRerecording.cpp . |
| 88 | if (m_StartTime == 0) return 1; | 88 | if (m_StartTime == 0) return 1; |
| 89 | 89 | ||
| 90 | // Return the final timer time if the timer is stopped | 90 | // Return the final timer time if the timer is stopped |
| 91 | if (!m_Running) return (m_LastTime - m_StartTime); | 91 | if (!m_Running) return (m_LastTime - m_StartTime); |
| 92 | 92 | ||
| 93 | return (GetTimeMs() - m_StartTime); | 93 | return (GetTimeMs() - m_StartTime); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | // Get the formatted time elapsed since the Start() | 96 | // Get the formatted time elapsed since the Start() |
| 97 | std::string Timer::GetTimeElapsedFormatted() const | 97 | std::string Timer::GetTimeElapsedFormatted() const |
| 98 | { | 98 | { |
| 99 | // If we have not started yet, return zero | 99 | // If we have not started yet, return zero |
| 100 | if (m_StartTime == 0) | 100 | if (m_StartTime == 0) |
| 101 | return "00:00:00:000"; | 101 | return "00:00:00:000"; |
| 102 | 102 | ||
| 103 | // The number of milliseconds since the start. | 103 | // The number of milliseconds since the start. |
| 104 | // Use a different value if the timer is stopped. | 104 | // Use a different value if the timer is stopped. |
| 105 | u64 Milliseconds; | 105 | u64 Milliseconds; |
| 106 | if (m_Running) | 106 | if (m_Running) |
| 107 | Milliseconds = GetTimeMs() - m_StartTime; | 107 | Milliseconds = GetTimeMs() - m_StartTime; |
| 108 | else | 108 | else |
| 109 | Milliseconds = m_LastTime - m_StartTime; | 109 | Milliseconds = m_LastTime - m_StartTime; |
| 110 | // Seconds | 110 | // Seconds |
| 111 | u32 Seconds = (u32)(Milliseconds / 1000); | 111 | u32 Seconds = (u32)(Milliseconds / 1000); |
| 112 | // Minutes | 112 | // Minutes |
| 113 | u32 Minutes = Seconds / 60; | 113 | u32 Minutes = Seconds / 60; |
| 114 | // Hours | 114 | // Hours |
| 115 | u32 Hours = Minutes / 60; | 115 | u32 Hours = Minutes / 60; |
| 116 | 116 | ||
| 117 | std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i", | 117 | std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i", |
| 118 | Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000); | 118 | Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000); |
| 119 | return TmpStr; | 119 | return TmpStr; |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | // Get current time | 122 | // Get current time |
| 123 | void Timer::IncreaseResolution() | 123 | void Timer::IncreaseResolution() |
| 124 | { | 124 | { |
| 125 | #ifdef _WIN32 | 125 | #ifdef _WIN32 |
| 126 | timeBeginPeriod(1); | 126 | timeBeginPeriod(1); |
| 127 | #endif | 127 | #endif |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | void Timer::RestoreResolution() | 130 | void Timer::RestoreResolution() |
| 131 | { | 131 | { |
| 132 | #ifdef _WIN32 | 132 | #ifdef _WIN32 |
| 133 | timeEndPeriod(1); | 133 | timeEndPeriod(1); |
| 134 | #endif | 134 | #endif |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | // Get the number of seconds since January 1 1970 | 137 | // Get the number of seconds since January 1 1970 |
| 138 | u64 Timer::GetTimeSinceJan1970() | 138 | u64 Timer::GetTimeSinceJan1970() |
| 139 | { | 139 | { |
| 140 | time_t ltime; | 140 | time_t ltime; |
| 141 | time(<ime); | 141 | time(<ime); |
| 142 | return((u64)ltime); | 142 | return((u64)ltime); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | u64 Timer::GetLocalTimeSinceJan1970() | 145 | u64 Timer::GetLocalTimeSinceJan1970() |
| 146 | { | 146 | { |
| 147 | time_t sysTime, tzDiff, tzDST; | 147 | time_t sysTime, tzDiff, tzDST; |
| 148 | struct tm * gmTime; | 148 | struct tm * gmTime; |
| 149 | 149 | ||
| 150 | time(&sysTime); | 150 | time(&sysTime); |
| 151 | 151 | ||
| 152 | // Account for DST where needed | 152 | // Account for DST where needed |
| 153 | gmTime = localtime(&sysTime); | 153 | gmTime = localtime(&sysTime); |
| 154 | if(gmTime->tm_isdst == 1) | 154 | if(gmTime->tm_isdst == 1) |
| 155 | tzDST = 3600; | 155 | tzDST = 3600; |
| 156 | else | 156 | else |
| 157 | tzDST = 0; | 157 | tzDST = 0; |
| 158 | 158 | ||
| 159 | // Lazy way to get local time in sec | 159 | // Lazy way to get local time in sec |
| 160 | gmTime = gmtime(&sysTime); | 160 | gmTime = gmtime(&sysTime); |
| 161 | tzDiff = sysTime - mktime(gmTime); | 161 | tzDiff = sysTime - mktime(gmTime); |
| 162 | 162 | ||
| 163 | return (u64)(sysTime + tzDiff + tzDST); | 163 | return (u64)(sysTime + tzDiff + tzDST); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | // Return the current time formatted as Minutes:Seconds:Milliseconds | 166 | // Return the current time formatted as Minutes:Seconds:Milliseconds |
| 167 | // in the form 00:00:000. | 167 | // in the form 00:00:000. |
| 168 | std::string Timer::GetTimeFormatted() | 168 | std::string Timer::GetTimeFormatted() |
| 169 | { | 169 | { |
| 170 | time_t sysTime; | 170 | time_t sysTime; |
| 171 | struct tm * gmTime; | 171 | struct tm * gmTime; |
| 172 | char formattedTime[13]; | 172 | char formattedTime[13]; |
| 173 | char tmp[13]; | 173 | char tmp[13]; |
| 174 | 174 | ||
| 175 | time(&sysTime); | 175 | time(&sysTime); |
| 176 | gmTime = localtime(&sysTime); | 176 | gmTime = localtime(&sysTime); |
| 177 | 177 | ||
| 178 | strftime(tmp, 6, "%M:%S", gmTime); | 178 | strftime(tmp, 6, "%M:%S", gmTime); |
| 179 | 179 | ||
| 180 | // Now tack on the milliseconds | 180 | // Now tack on the milliseconds |
| 181 | #ifdef _WIN32 | 181 | #ifdef _WIN32 |
| 182 | struct timeb tp; | 182 | struct timeb tp; |
| 183 | (void)::ftime(&tp); | 183 | (void)::ftime(&tp); |
| 184 | sprintf(formattedTime, "%s:%03i", tmp, tp.millitm); | 184 | sprintf(formattedTime, "%s:%03i", tmp, tp.millitm); |
| 185 | #else | 185 | #else |
| 186 | struct timeval t; | 186 | struct timeval t; |
| 187 | (void)gettimeofday(&t, NULL); | 187 | (void)gettimeofday(&t, NULL); |
| 188 | sprintf(formattedTime, "%s:%03d", tmp, (int)(t.tv_usec / 1000)); | 188 | sprintf(formattedTime, "%s:%03d", tmp, (int)(t.tv_usec / 1000)); |
| 189 | #endif | 189 | #endif |
| 190 | 190 | ||
| 191 | return std::string(formattedTime); | 191 | return std::string(formattedTime); |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | // Returns a timestamp with decimals for precise time comparisons | 194 | // Returns a timestamp with decimals for precise time comparisons |
| @@ -196,31 +196,31 @@ std::string Timer::GetTimeFormatted() | |||
| 196 | double Timer::GetDoubleTime() | 196 | double Timer::GetDoubleTime() |
| 197 | { | 197 | { |
| 198 | #ifdef _WIN32 | 198 | #ifdef _WIN32 |
| 199 | struct timeb tp; | 199 | struct timeb tp; |
| 200 | (void)::ftime(&tp); | 200 | (void)::ftime(&tp); |
| 201 | #else | 201 | #else |
| 202 | struct timeval t; | 202 | struct timeval t; |
| 203 | (void)gettimeofday(&t, NULL); | 203 | (void)gettimeofday(&t, NULL); |
| 204 | #endif | 204 | #endif |
| 205 | // Get continuous timestamp | 205 | // Get continuous timestamp |
| 206 | u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); | 206 | u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); |
| 207 | 207 | ||
| 208 | // Remove a few years. We only really want enough seconds to make | 208 | // Remove a few years. We only really want enough seconds to make |
| 209 | // sure that we are detecting actual actions, perhaps 60 seconds is | 209 | // sure that we are detecting actual actions, perhaps 60 seconds is |
| 210 | // enough really, but I leave a year of seconds anyway, in case the | 210 | // enough really, but I leave a year of seconds anyway, in case the |
| 211 | // user's clock is incorrect or something like that. | 211 | // user's clock is incorrect or something like that. |
| 212 | TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); | 212 | TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); |
| 213 | 213 | ||
| 214 | // Make a smaller integer that fits in the double | 214 | // Make a smaller integer that fits in the double |
| 215 | u32 Seconds = (u32)TmpSeconds; | 215 | u32 Seconds = (u32)TmpSeconds; |
| 216 | #ifdef _WIN32 | 216 | #ifdef _WIN32 |
| 217 | double ms = tp.millitm / 1000.0 / 1000.0; | 217 | double ms = tp.millitm / 1000.0 / 1000.0; |
| 218 | #else | 218 | #else |
| 219 | double ms = t.tv_usec / 1000000.0; | 219 | double ms = t.tv_usec / 1000000.0; |
| 220 | #endif | 220 | #endif |
| 221 | double TmpTime = Seconds + ms; | 221 | double TmpTime = Seconds + ms; |
| 222 | 222 | ||
| 223 | return TmpTime; | 223 | return TmpTime; |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | } // Namespace Common | 226 | } // Namespace Common |
diff --git a/src/common/src/timer.h b/src/common/src/timer.h index 9ee5719a3..20c86762a 100644 --- a/src/common/src/timer.h +++ b/src/common/src/timer.h | |||
| @@ -13,32 +13,32 @@ namespace Common | |||
| 13 | class Timer | 13 | class Timer |
| 14 | { | 14 | { |
| 15 | public: | 15 | public: |
| 16 | Timer(); | 16 | Timer(); |
| 17 | 17 | ||
| 18 | void Start(); | 18 | void Start(); |
| 19 | void Stop(); | 19 | void Stop(); |
| 20 | void Update(); | 20 | void Update(); |
| 21 | 21 | ||
| 22 | // The time difference is always returned in milliseconds, regardless of alternative internal representation | 22 | // The time difference is always returned in milliseconds, regardless of alternative internal representation |
| 23 | u64 GetTimeDifference(); | 23 | u64 GetTimeDifference(); |
| 24 | void AddTimeDifference(); | 24 | void AddTimeDifference(); |
| 25 | 25 | ||
| 26 | static void IncreaseResolution(); | 26 | static void IncreaseResolution(); |
| 27 | static void RestoreResolution(); | 27 | static void RestoreResolution(); |
| 28 | static u64 GetTimeSinceJan1970(); | 28 | static u64 GetTimeSinceJan1970(); |
| 29 | static u64 GetLocalTimeSinceJan1970(); | 29 | static u64 GetLocalTimeSinceJan1970(); |
| 30 | static double GetDoubleTime(); | 30 | static double GetDoubleTime(); |
| 31 | 31 | ||
| 32 | static std::string GetTimeFormatted(); | 32 | static std::string GetTimeFormatted(); |
| 33 | std::string GetTimeElapsedFormatted() const; | 33 | std::string GetTimeElapsedFormatted() const; |
| 34 | u64 GetTimeElapsed(); | 34 | u64 GetTimeElapsed(); |
| 35 | 35 | ||
| 36 | static u32 GetTimeMs(); | 36 | static u32 GetTimeMs(); |
| 37 | 37 | ||
| 38 | private: | 38 | private: |
| 39 | u64 m_LastTime; | 39 | u64 m_LastTime; |
| 40 | u64 m_StartTime; | 40 | u64 m_StartTime; |
| 41 | bool m_Running; | 41 | bool m_Running; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | } // Namespace Common | 44 | } // Namespace Common |
diff --git a/src/common/src/utf8.cpp b/src/common/src/utf8.cpp index 283cffdc2..9aa8088ef 100644 --- a/src/common/src/utf8.cpp +++ b/src/common/src/utf8.cpp | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | 31 | ||
| 32 | // is start of UTF sequence | 32 | // is start of UTF sequence |
| 33 | inline bool isutf(char c) { | 33 | inline bool isutf(char c) { |
| 34 | return (c & 0xC0) != 0x80; | 34 | return (c & 0xC0) != 0x80; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | static const u32 offsetsFromUTF8[6] = { | 37 | static const u32 offsetsFromUTF8[6] = { |
| @@ -47,7 +47,7 @@ static const u8 trailingBytesForUTF8[256] = { | |||
| 47 | 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, | 47 | 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, |
| 48 | 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, | 48 | 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, |
| 49 | 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, | 49 | 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, |
| 50 | 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, | 50 | 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, |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | /* returns length of next utf-8 sequence */ | 53 | /* returns length of next utf-8 sequence */ |
| @@ -405,59 +405,59 @@ int u8_is_locale_utf8(const char *locale) | |||
| 405 | } | 405 | } |
| 406 | 406 | ||
| 407 | int UTF8StringNonASCIICount(const char *utf8string) { | 407 | int UTF8StringNonASCIICount(const char *utf8string) { |
| 408 | UTF8 utf(utf8string); | 408 | UTF8 utf(utf8string); |
| 409 | int count = 0; | 409 | int count = 0; |
| 410 | while (!utf.end()) { | 410 | while (!utf.end()) { |
| 411 | int c = utf.next(); | 411 | int c = utf.next(); |
| 412 | if (c > 127) | 412 | if (c > 127) |
| 413 | ++count; | 413 | ++count; |
| 414 | } | 414 | } |
| 415 | return count; | 415 | return count; |
| 416 | } | 416 | } |
| 417 | 417 | ||
| 418 | bool UTF8StringHasNonASCII(const char *utf8string) { | 418 | bool UTF8StringHasNonASCII(const char *utf8string) { |
| 419 | return UTF8StringNonASCIICount(utf8string) > 0; | 419 | return UTF8StringNonASCIICount(utf8string) > 0; |
| 420 | } | 420 | } |
| 421 | 421 | ||
| 422 | #ifdef _WIN32 | 422 | #ifdef _WIN32 |
| 423 | 423 | ||
| 424 | std::string ConvertWStringToUTF8(const wchar_t *wstr) { | 424 | std::string ConvertWStringToUTF8(const wchar_t *wstr) { |
| 425 | int len = (int)wcslen(wstr); | 425 | int len = (int)wcslen(wstr); |
| 426 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, NULL, NULL); | 426 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, NULL, NULL); |
| 427 | std::string s; | 427 | std::string s; |
| 428 | s.resize(size); | 428 | s.resize(size); |
| 429 | if (size > 0) { | 429 | if (size > 0) { |
| 430 | WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, NULL, NULL); | 430 | WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, NULL, NULL); |
| 431 | } | 431 | } |
| 432 | return s; | 432 | return s; |
| 433 | } | 433 | } |
| 434 | 434 | ||
| 435 | std::string ConvertWStringToUTF8(const std::wstring &wstr) { | 435 | std::string ConvertWStringToUTF8(const std::wstring &wstr) { |
| 436 | int len = (int)wstr.size(); | 436 | int len = (int)wstr.size(); |
| 437 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL); | 437 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL); |
| 438 | std::string s; | 438 | std::string s; |
| 439 | s.resize(size); | 439 | s.resize(size); |
| 440 | if (size > 0) { | 440 | if (size > 0) { |
| 441 | WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, NULL, NULL); | 441 | WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, NULL, NULL); |
| 442 | } | 442 | } |
| 443 | return s; | 443 | return s; |
| 444 | } | 444 | } |
| 445 | 445 | ||
| 446 | void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { | 446 | void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { |
| 447 | int len = (int)source.size(); | 447 | int len = (int)source.size(); |
| 448 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); | 448 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); |
| 449 | MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size)); | 449 | MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size)); |
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | std::wstring ConvertUTF8ToWString(const std::string &source) { | 452 | std::wstring ConvertUTF8ToWString(const std::string &source) { |
| 453 | int len = (int)source.size(); | 453 | int len = (int)source.size(); |
| 454 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); | 454 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); |
| 455 | std::wstring str; | 455 | std::wstring str; |
| 456 | str.resize(size); | 456 | str.resize(size); |
| 457 | if (size > 0) { | 457 | if (size > 0) { |
| 458 | MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, &str[0], size); | 458 | MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, &str[0], size); |
| 459 | } | 459 | } |
| 460 | return str; | 460 | return str; |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | #endif \ No newline at end of file | 463 | #endif \ No newline at end of file |
diff --git a/src/common/src/utf8.h b/src/common/src/utf8.h index 8df4ffa3a..36cf75713 100644 --- a/src/common/src/utf8.h +++ b/src/common/src/utf8.h | |||
| @@ -25,29 +25,29 @@ int u8_strlen(const char *s); | |||
| 25 | 25 | ||
| 26 | class UTF8 { | 26 | class UTF8 { |
| 27 | public: | 27 | public: |
| 28 | static const u32 INVALID = (u32)-1; | 28 | static const u32 INVALID = (u32)-1; |
| 29 | UTF8(const char *c) : c_(c), index_(0) {} | 29 | UTF8(const char *c) : c_(c), index_(0) {} |
| 30 | bool end() const { return c_[index_] == 0; } | 30 | bool end() const { return c_[index_] == 0; } |
| 31 | u32 next() { | 31 | u32 next() { |
| 32 | return u8_nextchar(c_, &index_); | 32 | return u8_nextchar(c_, &index_); |
| 33 | } | 33 | } |
| 34 | u32 peek() { | 34 | u32 peek() { |
| 35 | int tempIndex = index_; | 35 | int tempIndex = index_; |
| 36 | return u8_nextchar(c_, &tempIndex); | 36 | return u8_nextchar(c_, &tempIndex); |
| 37 | } | 37 | } |
| 38 | int length() const { | 38 | int length() const { |
| 39 | return u8_strlen(c_); | 39 | return u8_strlen(c_); |
| 40 | } | 40 | } |
| 41 | int byteIndex() const { | 41 | int byteIndex() const { |
| 42 | return index_; | 42 | return index_; |
| 43 | } | 43 | } |
| 44 | static int encode(char *dest, u32 ch) { | 44 | static int encode(char *dest, u32 ch) { |
| 45 | return u8_wc_toutf8(dest, ch); | 45 | return u8_wc_toutf8(dest, ch); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | private: | 48 | private: |
| 49 | const char *c_; | 49 | const char *c_; |
| 50 | int index_; | 50 | int index_; |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | int UTF8StringNonASCIICount(const char *utf8string); | 53 | int UTF8StringNonASCIICount(const char *utf8string); |
diff --git a/src/common/src/version.cpp b/src/common/src/version.cpp index 25e99b21a..01890dbb6 100644 --- a/src/common/src/version.cpp +++ b/src/common/src/version.cpp | |||
| @@ -6,22 +6,22 @@ | |||
| 6 | #include "scm_rev.h" | 6 | #include "scm_rev.h" |
| 7 | 7 | ||
| 8 | #ifdef _DEBUG | 8 | #ifdef _DEBUG |
| 9 | #define BUILD_TYPE_STR "Debug " | 9 | #define BUILD_TYPE_STR "Debug " |
| 10 | #elif defined DEBUGFAST | 10 | #elif defined DEBUGFAST |
| 11 | #define BUILD_TYPE_STR "DebugFast " | 11 | #define BUILD_TYPE_STR "DebugFast " |
| 12 | #else | 12 | #else |
| 13 | #define BUILD_TYPE_STR "" | 13 | #define BUILD_TYPE_STR "" |
| 14 | #endif | 14 | #endif |
| 15 | 15 | ||
| 16 | const char *scm_rev_str = "emu " | 16 | const char *scm_rev_str = "emu " |
| 17 | #if !SCM_IS_MASTER | 17 | #if !SCM_IS_MASTER |
| 18 | "[" SCM_BRANCH_STR "] " | 18 | "[" SCM_BRANCH_STR "] " |
| 19 | #endif | 19 | #endif |
| 20 | 20 | ||
| 21 | #ifdef __INTEL_COMPILER | 21 | #ifdef __INTEL_COMPILER |
| 22 | BUILD_TYPE_STR SCM_DESC_STR "-ICC"; | 22 | BUILD_TYPE_STR SCM_DESC_STR "-ICC"; |
| 23 | #else | 23 | #else |
| 24 | BUILD_TYPE_STR SCM_DESC_STR; | 24 | BUILD_TYPE_STR SCM_DESC_STR; |
| 25 | #endif | 25 | #endif |
| 26 | 26 | ||
| 27 | #ifdef _M_X64 | 27 | #ifdef _M_X64 |
| @@ -29,7 +29,7 @@ const char *scm_rev_str = "emu " | |||
| 29 | #else | 29 | #else |
| 30 | #ifdef _M_ARM | 30 | #ifdef _M_ARM |
| 31 | #define NP_ARCH "ARM" | 31 | #define NP_ARCH "ARM" |
| 32 | #else | 32 | #else |
| 33 | #define NP_ARCH "x86" | 33 | #define NP_ARCH "x86" |
| 34 | #endif | 34 | #endif |
| 35 | #endif | 35 | #endif |