diff options
| author | 2014-12-29 19:47:41 -0800 | |
|---|---|---|
| committer | 2014-12-29 19:47:41 -0800 | |
| commit | 8ba9ac0f74abb0408a26207a76a0c1808bad8de0 (patch) | |
| tree | f1c7c3393fa726435b5b90bf335567c93e528ef1 /src/common | |
| parent | Add comment regarding __WIN32__ in SkyEye code (diff) | |
| parent | Merge pull request #367 from bunnei/usat_ssat (diff) | |
| download | yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.gz yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.xz yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.zip | |
Fix merge conflicts
Diffstat (limited to 'src/common')
59 files changed, 1296 insertions, 1092 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 9d5a90762..3c3419bbc 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -3,14 +3,15 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in" "${CMAKE_CURRENT_SOU | |||
| 3 | 3 | ||
| 4 | set(SRCS | 4 | set(SRCS |
| 5 | break_points.cpp | 5 | break_points.cpp |
| 6 | console_listener.cpp | ||
| 7 | emu_window.cpp | 6 | emu_window.cpp |
| 8 | extended_trace.cpp | 7 | extended_trace.cpp |
| 9 | file_search.cpp | 8 | file_search.cpp |
| 10 | file_util.cpp | 9 | file_util.cpp |
| 11 | hash.cpp | 10 | hash.cpp |
| 12 | key_map.cpp | 11 | key_map.cpp |
| 13 | log_manager.cpp | 12 | logging/filter.cpp |
| 13 | logging/text_formatter.cpp | ||
| 14 | logging/backend.cpp | ||
| 14 | math_util.cpp | 15 | math_util.cpp |
| 15 | mem_arena.cpp | 16 | mem_arena.cpp |
| 16 | memory_util.cpp | 17 | memory_util.cpp |
| @@ -32,7 +33,7 @@ set(HEADERS | |||
| 32 | common_funcs.h | 33 | common_funcs.h |
| 33 | common_paths.h | 34 | common_paths.h |
| 34 | common_types.h | 35 | common_types.h |
| 35 | console_listener.h | 36 | concurrent_ring_buffer.h |
| 36 | cpu_detect.h | 37 | cpu_detect.h |
| 37 | debug_interface.h | 38 | debug_interface.h |
| 38 | emu_window.h | 39 | emu_window.h |
| @@ -44,13 +45,18 @@ set(HEADERS | |||
| 44 | key_map.h | 45 | key_map.h |
| 45 | linear_disk_cache.h | 46 | linear_disk_cache.h |
| 46 | log.h | 47 | log.h |
| 47 | log_manager.h | 48 | logging/text_formatter.h |
| 49 | logging/filter.h | ||
| 50 | logging/log.h | ||
| 51 | logging/backend.h | ||
| 52 | make_unique.h | ||
| 48 | math_util.h | 53 | math_util.h |
| 49 | mem_arena.h | 54 | mem_arena.h |
| 50 | memory_util.h | 55 | memory_util.h |
| 51 | msg_handler.h | 56 | msg_handler.h |
| 52 | platform.h | 57 | platform.h |
| 53 | scm_rev.h | 58 | scm_rev.h |
| 59 | scope_exit.h | ||
| 54 | string_util.h | 60 | string_util.h |
| 55 | swap.h | 61 | swap.h |
| 56 | symbols.h | 62 | symbols.h |
diff --git a/src/common/bit_field.h b/src/common/bit_field.h index 9e02210f9..8eab054b8 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | // Licensed under GPLv2 | 1 | // Licensed under GPLv2 or any later version |
| 2 | // Refer to the license.txt file included. | 2 | // Refer to the license.txt file included. |
| 3 | 3 | ||
| 4 | 4 | ||
| @@ -142,7 +142,7 @@ public: | |||
| 142 | 142 | ||
| 143 | __forceinline BitField& operator=(T val) | 143 | __forceinline BitField& operator=(T val) |
| 144 | { | 144 | { |
| 145 | storage = (storage & ~GetMask()) | (((StorageType)val << position) & GetMask()); | 145 | Assign(val); |
| 146 | return *this; | 146 | return *this; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| @@ -151,6 +151,10 @@ public: | |||
| 151 | return Value(); | 151 | return Value(); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | __forceinline void Assign(const T& value) { | ||
| 155 | storage = (storage & ~GetMask()) | (((StorageType)value << position) & GetMask()); | ||
| 156 | } | ||
| 157 | |||
| 154 | __forceinline T Value() const | 158 | __forceinline T Value() const |
| 155 | { | 159 | { |
| 156 | if (std::numeric_limits<T>::is_signed) | 160 | if (std::numeric_limits<T>::is_signed) |
| @@ -164,6 +168,12 @@ public: | |||
| 164 | } | 168 | } |
| 165 | } | 169 | } |
| 166 | 170 | ||
| 171 | // TODO: we may want to change this to explicit operator bool() if it's bug-free in VS2015 | ||
| 172 | __forceinline bool ToBool() const | ||
| 173 | { | ||
| 174 | return Value() != 0; | ||
| 175 | } | ||
| 176 | |||
| 167 | private: | 177 | private: |
| 168 | // StorageType is T for non-enum types and the underlying type of T if | 178 | // StorageType is T for non-enum types and the underlying type of T if |
| 169 | // T is an enumeration. Note that T is wrapped within an enable_if in the | 179 | // T is an enumeration. Note that T is wrapped within an enable_if in the |
diff --git a/src/common/break_points.cpp b/src/common/break_points.cpp index 25528b864..6696935fa 100644 --- a/src/common/break_points.cpp +++ b/src/common/break_points.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/common.h" | 5 | #include "common/common.h" |
| @@ -180,7 +180,7 @@ void TMemCheck::Action(DebugInterface *debug_interface, u32 iValue, u32 addr, | |||
| 180 | { | 180 | { |
| 181 | if (Log) | 181 | if (Log) |
| 182 | { | 182 | { |
| 183 | INFO_LOG(MEMMAP, "CHK %08x (%s) %s%i %0*x at %08x (%s)", | 183 | LOG_DEBUG(Debug_Breakpoint, "CHK %08x (%s) %s%i %0*x at %08x (%s)", |
| 184 | pc, debug_interface->getDescription(pc).c_str(), | 184 | pc, debug_interface->getDescription(pc).c_str(), |
| 185 | write ? "Write" : "Read", size*8, size*2, iValue, addr, | 185 | write ? "Write" : "Read", size*8, size*2, iValue, addr, |
| 186 | debug_interface->getDescription(addr).c_str() | 186 | debug_interface->getDescription(addr).c_str() |
diff --git a/src/common/break_points.h b/src/common/break_points.h index cf3884fbc..5557cd50e 100644 --- a/src/common/break_points.h +++ b/src/common/break_points.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/chunk_file.h b/src/common/chunk_file.h index 609784076..39a14dc81 100644 --- a/src/common/chunk_file.h +++ b/src/common/chunk_file.h | |||
| @@ -154,7 +154,7 @@ public: | |||
| 154 | Do(foundVersion); | 154 | Do(foundVersion); |
| 155 | 155 | ||
| 156 | if (error == ERROR_FAILURE || foundVersion < minVer || foundVersion > ver) { | 156 | if (error == ERROR_FAILURE || foundVersion < minVer || foundVersion > ver) { |
| 157 | WARN_LOG(COMMON, "Savestate failure: wrong version %d found for %s", foundVersion, title); | 157 | LOG_ERROR(Common, "Savestate failure: wrong version %d found for %s", foundVersion, title); |
| 158 | SetError(ERROR_FAILURE); | 158 | SetError(ERROR_FAILURE); |
| 159 | return PointerWrapSection(*this, -1, title); | 159 | return PointerWrapSection(*this, -1, title); |
| 160 | } | 160 | } |
| @@ -178,7 +178,14 @@ public: | |||
| 178 | case MODE_READ: if (memcmp(data, *ptr, size) != 0) return false; break; | 178 | case MODE_READ: if (memcmp(data, *ptr, size) != 0) return false; break; |
| 179 | case MODE_WRITE: memcpy(*ptr, data, size); break; | 179 | case MODE_WRITE: memcpy(*ptr, data, size); break; |
| 180 | case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything | 180 | case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything |
| 181 | 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; | 181 | case MODE_VERIFY: |
| 182 | for (int i = 0; i < size; i++) { | ||
| 183 | _dbg_assert_msg_(Common, ((u8*)data)[i] == (*ptr)[i], | ||
| 184 | "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", | ||
| 185 | ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], | ||
| 186 | (*ptr)[i], (*ptr)[i], &(*ptr)[i]); | ||
| 187 | } | ||
| 188 | break; | ||
| 182 | default: break; // throw an error? | 189 | default: break; // throw an error? |
| 183 | } | 190 | } |
| 184 | (*ptr) += size; | 191 | (*ptr) += size; |
| @@ -191,7 +198,14 @@ public: | |||
| 191 | case MODE_READ: memcpy(data, *ptr, size); break; | 198 | case MODE_READ: memcpy(data, *ptr, size); break; |
| 192 | case MODE_WRITE: memcpy(*ptr, data, size); break; | 199 | case MODE_WRITE: memcpy(*ptr, data, size); break; |
| 193 | case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything | 200 | case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything |
| 194 | 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; | 201 | case MODE_VERIFY: |
| 202 | for (int i = 0; i < size; i++) { | ||
| 203 | _dbg_assert_msg_(Common, ((u8*)data)[i] == (*ptr)[i], | ||
| 204 | "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", | ||
| 205 | ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], | ||
| 206 | (*ptr)[i], (*ptr)[i], &(*ptr)[i]); | ||
| 207 | } | ||
| 208 | break; | ||
| 195 | default: break; // throw an error? | 209 | default: break; // throw an error? |
| 196 | } | 210 | } |
| 197 | (*ptr) += size; | 211 | (*ptr) += size; |
| @@ -204,11 +218,11 @@ public: | |||
| 204 | { | 218 | { |
| 205 | for (auto it = x.begin(), end = x.end(); it != end; ++it) | 219 | for (auto it = x.begin(), end = x.end(); it != end; ++it) |
| 206 | { | 220 | { |
| 207 | if (it->second != NULL) | 221 | if (it->second != nullptr) |
| 208 | delete it->second; | 222 | delete it->second; |
| 209 | } | 223 | } |
| 210 | } | 224 | } |
| 211 | T *dv = NULL; | 225 | T *dv = nullptr; |
| 212 | DoMap(x, dv); | 226 | DoMap(x, dv); |
| 213 | } | 227 | } |
| 214 | 228 | ||
| @@ -264,11 +278,11 @@ public: | |||
| 264 | { | 278 | { |
| 265 | for (auto it = x.begin(), end = x.end(); it != end; ++it) | 279 | for (auto it = x.begin(), end = x.end(); it != end; ++it) |
| 266 | { | 280 | { |
| 267 | if (it->second != NULL) | 281 | if (it->second != nullptr) |
| 268 | delete it->second; | 282 | delete it->second; |
| 269 | } | 283 | } |
| 270 | } | 284 | } |
| 271 | T *dv = NULL; | 285 | T *dv = nullptr; |
| 272 | DoMultimap(x, dv); | 286 | DoMultimap(x, dv); |
| 273 | } | 287 | } |
| 274 | 288 | ||
| @@ -320,7 +334,7 @@ public: | |||
| 320 | template<class T> | 334 | template<class T> |
| 321 | void Do(std::vector<T *> &x) | 335 | void Do(std::vector<T *> &x) |
| 322 | { | 336 | { |
| 323 | T *dv = NULL; | 337 | T *dv = nullptr; |
| 324 | DoVector(x, dv); | 338 | DoVector(x, dv); |
| 325 | } | 339 | } |
| 326 | 340 | ||
| @@ -369,7 +383,7 @@ public: | |||
| 369 | template<class T> | 383 | template<class T> |
| 370 | void Do(std::deque<T *> &x) | 384 | void Do(std::deque<T *> &x) |
| 371 | { | 385 | { |
| 372 | T *dv = NULL; | 386 | T *dv = nullptr; |
| 373 | DoDeque(x, dv); | 387 | DoDeque(x, dv); |
| 374 | } | 388 | } |
| 375 | 389 | ||
| @@ -395,7 +409,7 @@ public: | |||
| 395 | template<class T> | 409 | template<class T> |
| 396 | void Do(std::list<T *> &x) | 410 | void Do(std::list<T *> &x) |
| 397 | { | 411 | { |
| 398 | T *dv = NULL; | 412 | T *dv = nullptr; |
| 399 | Do(x, dv); | 413 | Do(x, dv); |
| 400 | } | 414 | } |
| 401 | 415 | ||
| @@ -433,7 +447,7 @@ public: | |||
| 433 | { | 447 | { |
| 434 | for (auto it = x.begin(), end = x.end(); it != end; ++it) | 448 | for (auto it = x.begin(), end = x.end(); it != end; ++it) |
| 435 | { | 449 | { |
| 436 | if (*it != NULL) | 450 | if (*it != nullptr) |
| 437 | delete *it; | 451 | delete *it; |
| 438 | } | 452 | } |
| 439 | } | 453 | } |
| @@ -476,7 +490,7 @@ public: | |||
| 476 | break; | 490 | break; |
| 477 | 491 | ||
| 478 | default: | 492 | default: |
| 479 | ERROR_LOG(COMMON, "Savestate error: invalid mode %d.", mode); | 493 | LOG_ERROR(Common, "Savestate error: invalid mode %d.", mode); |
| 480 | } | 494 | } |
| 481 | } | 495 | } |
| 482 | 496 | ||
| @@ -490,7 +504,12 @@ public: | |||
| 490 | case MODE_READ: x = (char*)*ptr; break; | 504 | case MODE_READ: x = (char*)*ptr; break; |
| 491 | case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; | 505 | case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; |
| 492 | case MODE_MEASURE: break; | 506 | case MODE_MEASURE: break; |
| 493 | 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; | 507 | case MODE_VERIFY: |
| 508 | _dbg_assert_msg_(Common, | ||
| 509 | !strcmp(x.c_str(), (char*)*ptr), | ||
| 510 | "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", | ||
| 511 | x.c_str(), (char*)*ptr, ptr); | ||
| 512 | break; | ||
| 494 | } | 513 | } |
| 495 | (*ptr) += stringLen; | 514 | (*ptr) += stringLen; |
| 496 | } | 515 | } |
| @@ -504,7 +523,11 @@ public: | |||
| 504 | case MODE_READ: x = (wchar_t*)*ptr; break; | 523 | case MODE_READ: x = (wchar_t*)*ptr; break; |
| 505 | case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; | 524 | case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; |
| 506 | case MODE_MEASURE: break; | 525 | case MODE_MEASURE: break; |
| 507 | 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; | 526 | case MODE_VERIFY: |
| 527 | _dbg_assert_msg_(Common, x == (wchar_t*)*ptr, | ||
| 528 | "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", | ||
| 529 | x.c_str(), (wchar_t*)*ptr, ptr); | ||
| 530 | break; | ||
| 508 | } | 531 | } |
| 509 | (*ptr) += stringLen; | 532 | (*ptr) += stringLen; |
| 510 | } | 533 | } |
| @@ -518,7 +541,7 @@ public: | |||
| 518 | void DoClass(T *&x) { | 541 | void DoClass(T *&x) { |
| 519 | if (mode == MODE_READ) | 542 | if (mode == MODE_READ) |
| 520 | { | 543 | { |
| 521 | if (x != NULL) | 544 | if (x != nullptr) |
| 522 | delete x; | 545 | delete x; |
| 523 | x = new T(); | 546 | x = new T(); |
| 524 | } | 547 | } |
| @@ -567,7 +590,7 @@ public: | |||
| 567 | { | 590 | { |
| 568 | if (mode == MODE_READ) | 591 | if (mode == MODE_READ) |
| 569 | { | 592 | { |
| 570 | cur->next = 0; | 593 | cur->next = nullptr; |
| 571 | list_cur = cur; | 594 | list_cur = cur; |
| 572 | if (prev) | 595 | if (prev) |
| 573 | prev->next = cur; | 596 | prev->next = cur; |
| @@ -586,13 +609,13 @@ public: | |||
| 586 | if (mode == MODE_READ) | 609 | if (mode == MODE_READ) |
| 587 | { | 610 | { |
| 588 | if (prev) | 611 | if (prev) |
| 589 | prev->next = 0; | 612 | prev->next = nullptr; |
| 590 | if (list_end) | 613 | if (list_end) |
| 591 | *list_end = prev; | 614 | *list_end = prev; |
| 592 | if (list_cur) | 615 | if (list_cur) |
| 593 | { | 616 | { |
| 594 | if (list_start == list_cur) | 617 | if (list_start == list_cur) |
| 595 | list_start = 0; | 618 | list_start = nullptr; |
| 596 | do | 619 | do |
| 597 | { | 620 | { |
| 598 | LinkedListItem<T>* next = list_cur->next; | 621 | LinkedListItem<T>* next = list_cur->next; |
diff --git a/src/common/common.h b/src/common/common.h index 0d7934622..ba33373ae 100644 --- a/src/common/common.h +++ b/src/common/common.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index ddf3958cc..c2750a63c 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h | |||
| @@ -1,9 +1,12 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common_types.h" | ||
| 8 | #include <cstdlib> | ||
| 9 | |||
| 7 | #ifdef _WIN32 | 10 | #ifdef _WIN32 |
| 8 | #define SLEEP(x) Sleep(x) | 11 | #define SLEEP(x) Sleep(x) |
| 9 | #else | 12 | #else |
| @@ -73,6 +76,8 @@ inline u64 _rotr64(u64 x, unsigned int shift){ | |||
| 73 | } | 76 | } |
| 74 | 77 | ||
| 75 | #else // _MSC_VER | 78 | #else // _MSC_VER |
| 79 | #include <locale.h> | ||
| 80 | |||
| 76 | // Function Cross-Compatibility | 81 | // Function Cross-Compatibility |
| 77 | #define strcasecmp _stricmp | 82 | #define strcasecmp _stricmp |
| 78 | #define strncasecmp _strnicmp | 83 | #define strncasecmp _strnicmp |
| @@ -106,7 +111,7 @@ inline u64 _rotr64(u64 x, unsigned int shift){ | |||
| 106 | // Restore the global locale | 111 | // Restore the global locale |
| 107 | _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); | 112 | _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); |
| 108 | } | 113 | } |
| 109 | else if(new_locale != NULL) | 114 | else if(new_locale != nullptr) |
| 110 | { | 115 | { |
| 111 | // Configure the thread to set the locale only for this thread | 116 | // Configure the thread to set the locale only for this thread |
| 112 | _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); | 117 | _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); |
diff --git a/src/common/common_paths.h b/src/common/common_paths.h index ae08d082a..9d62a8368 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| @@ -29,19 +29,6 @@ | |||
| 29 | #endif | 29 | #endif |
| 30 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | // Shared data dirs (Sys and shared User for linux) | ||
| 33 | #ifdef _WIN32 | ||
| 34 | #define SYSDATA_DIR "sys" | ||
| 35 | #else | ||
| 36 | #ifdef DATA_DIR | ||
| 37 | #define SYSDATA_DIR DATA_DIR "sys" | ||
| 38 | #define SHARED_USER_DIR DATA_DIR USERDATA_DIR DIR_SEP | ||
| 39 | #else | ||
| 40 | #define SYSDATA_DIR "sys" | ||
| 41 | #define SHARED_USER_DIR ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP | ||
| 42 | #endif | ||
| 43 | #endif | ||
| 44 | |||
| 45 | // Dirs in both User and Sys | 32 | // Dirs in both User and Sys |
| 46 | #define EUR_DIR "EUR" | 33 | #define EUR_DIR "EUR" |
| 47 | #define USA_DIR "USA" | 34 | #define USA_DIR "USA" |
| @@ -53,6 +40,9 @@ | |||
| 53 | #define MAPS_DIR "maps" | 40 | #define MAPS_DIR "maps" |
| 54 | #define CACHE_DIR "cache" | 41 | #define CACHE_DIR "cache" |
| 55 | #define SDMC_DIR "sdmc" | 42 | #define SDMC_DIR "sdmc" |
| 43 | #define SAVEDATA_DIR "savedata" | ||
| 44 | #define SYSDATA_DIR "sysdata" | ||
| 45 | #define SYSSAVEDATA_DIR "syssavedata" | ||
| 56 | #define SHADERCACHE_DIR "shader_cache" | 46 | #define SHADERCACHE_DIR "shader_cache" |
| 57 | #define STATESAVES_DIR "state_saves" | 47 | #define STATESAVES_DIR "state_saves" |
| 58 | #define SCREENSHOTS_DIR "screenShots" | 48 | #define SCREENSHOTS_DIR "screenShots" |
| @@ -70,6 +60,9 @@ | |||
| 70 | #define DEBUGGER_CONFIG "debugger.ini" | 60 | #define DEBUGGER_CONFIG "debugger.ini" |
| 71 | #define LOGGER_CONFIG "logger.ini" | 61 | #define LOGGER_CONFIG "logger.ini" |
| 72 | 62 | ||
| 63 | // Sys files | ||
| 64 | #define SHARED_FONT "shared_font.bin" | ||
| 65 | |||
| 73 | // Files in the directory returned by GetUserPath(D_LOGS_IDX) | 66 | // Files in the directory returned by GetUserPath(D_LOGS_IDX) |
| 74 | #define MAIN_LOG "emu.log" | 67 | #define MAIN_LOG "emu.log" |
| 75 | 68 | ||
diff --git a/src/common/common_types.h b/src/common/common_types.h index fcc8b9a4e..c74c74f0f 100644 --- a/src/common/common_types.h +++ b/src/common/common_types.h | |||
| @@ -41,8 +41,6 @@ typedef std::int64_t s64; ///< 64-bit signed int | |||
| 41 | typedef float f32; ///< 32-bit floating point | 41 | typedef float f32; ///< 32-bit floating point |
| 42 | typedef double f64; ///< 64-bit floating point | 42 | typedef double f64; ///< 64-bit floating point |
| 43 | 43 | ||
| 44 | #include "common/common.h" | ||
| 45 | |||
| 46 | /// Union for fast 16-bit type casting | 44 | /// Union for fast 16-bit type casting |
| 47 | union t16 { | 45 | union t16 { |
| 48 | u8 _u8[2]; ///< 8-bit unsigned char(s) | 46 | u8 _u8[2]; ///< 8-bit unsigned char(s) |
diff --git a/src/common/concurrent_ring_buffer.h b/src/common/concurrent_ring_buffer.h new file mode 100644 index 000000000..311bb01f4 --- /dev/null +++ b/src/common/concurrent_ring_buffer.h | |||
| @@ -0,0 +1,164 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <condition_variable> | ||
| 9 | #include <cstdint> | ||
| 10 | #include <mutex> | ||
| 11 | #include <thread> | ||
| 12 | |||
| 13 | #include "common/common.h" // for NonCopyable | ||
| 14 | #include "common/log.h" // for _dbg_assert_ | ||
| 15 | |||
| 16 | namespace Common { | ||
| 17 | |||
| 18 | /** | ||
| 19 | * A MPMC (Multiple-Producer Multiple-Consumer) concurrent ring buffer. This data structure permits | ||
| 20 | * multiple threads to push and pop from a queue of bounded size. | ||
| 21 | */ | ||
| 22 | template <typename T, size_t ArraySize> | ||
| 23 | class ConcurrentRingBuffer : private NonCopyable { | ||
| 24 | public: | ||
| 25 | /// Value returned by the popping functions when the queue has been closed. | ||
| 26 | static const size_t QUEUE_CLOSED = -1; | ||
| 27 | |||
| 28 | ConcurrentRingBuffer() {} | ||
| 29 | |||
| 30 | ~ConcurrentRingBuffer() { | ||
| 31 | // If for whatever reason the queue wasn't completely drained, destroy the left over items. | ||
| 32 | for (size_t i = reader_index, end = writer_index; i != end; i = (i + 1) % ArraySize) { | ||
| 33 | Data()[i].~T(); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | /** | ||
| 38 | * Pushes a value to the queue. If the queue is full, this method will block. Does nothing if | ||
| 39 | * the queue is closed. | ||
| 40 | */ | ||
| 41 | void Push(T val) { | ||
| 42 | std::unique_lock<std::mutex> lock(mutex); | ||
| 43 | if (closed) { | ||
| 44 | return; | ||
| 45 | } | ||
| 46 | |||
| 47 | // If the buffer is full, wait | ||
| 48 | writer.wait(lock, [&]{ | ||
| 49 | return (writer_index + 1) % ArraySize != reader_index; | ||
| 50 | }); | ||
| 51 | |||
| 52 | T* item = &Data()[writer_index]; | ||
| 53 | new (item) T(std::move(val)); | ||
| 54 | |||
| 55 | writer_index = (writer_index + 1) % ArraySize; | ||
| 56 | |||
| 57 | // Wake up waiting readers | ||
| 58 | lock.unlock(); | ||
| 59 | reader.notify_one(); | ||
| 60 | } | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Pops up to `dest_len` items from the queue, storing them in `dest`. This function will not | ||
| 64 | * block, and might return 0 values if there are no elements in the queue when it is called. | ||
| 65 | * | ||
| 66 | * @return The number of elements stored in `dest`. If the queue has been closed, returns | ||
| 67 | * `QUEUE_CLOSED`. | ||
| 68 | */ | ||
| 69 | size_t Pop(T* dest, size_t dest_len) { | ||
| 70 | std::unique_lock<std::mutex> lock(mutex); | ||
| 71 | if (closed && !CanRead()) { | ||
| 72 | return QUEUE_CLOSED; | ||
| 73 | } | ||
| 74 | return PopInternal(dest, dest_len); | ||
| 75 | } | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Pops up to `dest_len` items from the queue, storing them in `dest`. This function will block | ||
| 79 | * if there are no elements in the queue when it is called. | ||
| 80 | * | ||
| 81 | * @return The number of elements stored in `dest`. If the queue has been closed, returns | ||
| 82 | * `QUEUE_CLOSED`. | ||
| 83 | */ | ||
| 84 | size_t BlockingPop(T* dest, size_t dest_len) { | ||
| 85 | std::unique_lock<std::mutex> lock(mutex); | ||
| 86 | if (closed && !CanRead()) { | ||
| 87 | return QUEUE_CLOSED; | ||
| 88 | } | ||
| 89 | |||
| 90 | while (!CanRead()) { | ||
| 91 | reader.wait(lock); | ||
| 92 | if (closed && !CanRead()) { | ||
| 93 | return QUEUE_CLOSED; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | _dbg_assert_(Common, CanRead()); | ||
| 97 | return PopInternal(dest, dest_len); | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Closes the queue. After calling this method, `Push` operations won't have any effect, and | ||
| 102 | * `PopMany` and `PopManyBlock` will start returning `QUEUE_CLOSED`. This is intended to allow | ||
| 103 | * a graceful shutdown of all consumers. | ||
| 104 | */ | ||
| 105 | void Close() { | ||
| 106 | std::unique_lock<std::mutex> lock(mutex); | ||
| 107 | closed = true; | ||
| 108 | // We need to wake up any reader that are waiting for an item that will never come. | ||
| 109 | lock.unlock(); | ||
| 110 | reader.notify_all(); | ||
| 111 | } | ||
| 112 | |||
| 113 | /// Returns true if `Close()` has been called. | ||
| 114 | bool IsClosed() const { | ||
| 115 | return closed; | ||
| 116 | } | ||
| 117 | |||
| 118 | private: | ||
| 119 | size_t PopInternal(T* dest, size_t dest_len) { | ||
| 120 | size_t output_count = 0; | ||
| 121 | while (output_count < dest_len && CanRead()) { | ||
| 122 | _dbg_assert_(Common, CanRead()); | ||
| 123 | |||
| 124 | T* item = &Data()[reader_index]; | ||
| 125 | T out_val = std::move(*item); | ||
| 126 | item->~T(); | ||
| 127 | |||
| 128 | size_t prev_index = (reader_index + ArraySize - 1) % ArraySize; | ||
| 129 | reader_index = (reader_index + 1) % ArraySize; | ||
| 130 | if (writer_index == prev_index) { | ||
| 131 | writer.notify_one(); | ||
| 132 | } | ||
| 133 | dest[output_count++] = std::move(out_val); | ||
| 134 | } | ||
| 135 | return output_count; | ||
| 136 | } | ||
| 137 | |||
| 138 | bool CanRead() const { | ||
| 139 | return reader_index != writer_index; | ||
| 140 | } | ||
| 141 | |||
| 142 | T* Data() { | ||
| 143 | return static_cast<T*>(static_cast<void*>(&storage)); | ||
| 144 | } | ||
| 145 | |||
| 146 | /// Storage for entries | ||
| 147 | typename std::aligned_storage<ArraySize * sizeof(T), | ||
| 148 | std::alignment_of<T>::value>::type storage; | ||
| 149 | |||
| 150 | /// Data is valid in the half-open interval [reader, writer). If they are `QUEUE_CLOSED` then the | ||
| 151 | /// queue has been closed. | ||
| 152 | size_t writer_index = 0, reader_index = 0; | ||
| 153 | // True if the queue has been closed. | ||
| 154 | bool closed = false; | ||
| 155 | |||
| 156 | /// Mutex that protects the entire data structure. | ||
| 157 | std::mutex mutex; | ||
| 158 | /// Signaling wakes up reader which is waiting for storage to be non-empty. | ||
| 159 | std::condition_variable reader; | ||
| 160 | /// Signaling wakes up writer which is waiting for storage to be non-full. | ||
| 161 | std::condition_variable writer; | ||
| 162 | }; | ||
| 163 | |||
| 164 | } // namespace | ||
diff --git a/src/common/console_listener.cpp b/src/common/console_listener.cpp deleted file mode 100644 index d7f27c358..000000000 --- a/src/common/console_listener.cpp +++ /dev/null | |||
| @@ -1,319 +0,0 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | ||
| 2 | // Licensed under GPLv2 | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | |||
| 7 | #ifdef _WIN32 | ||
| 8 | #include <windows.h> | ||
| 9 | #include <array> | ||
| 10 | #endif | ||
| 11 | |||
| 12 | #include "common/common.h" | ||
| 13 | #include "common/log_manager.h" // Common | ||
| 14 | #include "common/console_listener.h" // Common | ||
| 15 | |||
| 16 | ConsoleListener::ConsoleListener() | ||
| 17 | { | ||
| 18 | #ifdef _WIN32 | ||
| 19 | hConsole = NULL; | ||
| 20 | bUseColor = true; | ||
| 21 | #else | ||
| 22 | bUseColor = isatty(fileno(stdout)); | ||
| 23 | #endif | ||
| 24 | } | ||
| 25 | |||
| 26 | ConsoleListener::~ConsoleListener() | ||
| 27 | { | ||
| 28 | Close(); | ||
| 29 | } | ||
| 30 | |||
| 31 | // 100, 100, "Dolphin Log Console" | ||
| 32 | // Open console window - width and height is the size of console window | ||
| 33 | // Name is the window title | ||
| 34 | void ConsoleListener::Open(bool Hidden, int Width, int Height, const char *Title) | ||
| 35 | { | ||
| 36 | #ifdef _WIN32 | ||
| 37 | if (!GetConsoleWindow()) | ||
| 38 | { | ||
| 39 | // Open the console window and create the window handle for GetStdHandle() | ||
| 40 | AllocConsole(); | ||
| 41 | // Hide | ||
| 42 | if (Hidden) ShowWindow(GetConsoleWindow(), SW_HIDE); | ||
| 43 | // Save the window handle that AllocConsole() created | ||
| 44 | hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||
| 45 | // Set the console window title | ||
| 46 | SetConsoleTitle(Common::UTF8ToTStr(Title).c_str()); | ||
| 47 | // Set letter space | ||
| 48 | LetterSpace(80, 4000); | ||
| 49 | //MoveWindow(GetConsoleWindow(), 200,200, 800,800, true); | ||
| 50 | } | ||
| 51 | else | ||
| 52 | { | ||
| 53 | hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||
| 54 | } | ||
| 55 | #endif | ||
| 56 | } | ||
| 57 | |||
| 58 | void ConsoleListener::UpdateHandle() | ||
| 59 | { | ||
| 60 | #ifdef _WIN32 | ||
| 61 | hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||
| 62 | #endif | ||
| 63 | } | ||
| 64 | |||
| 65 | // Close the console window and close the eventual file handle | ||
| 66 | void ConsoleListener::Close() | ||
| 67 | { | ||
| 68 | #ifdef _WIN32 | ||
| 69 | if (hConsole == NULL) | ||
| 70 | return; | ||
| 71 | FreeConsole(); | ||
| 72 | hConsole = NULL; | ||
| 73 | #else | ||
| 74 | fflush(NULL); | ||
| 75 | #endif | ||
| 76 | } | ||
| 77 | |||
| 78 | bool ConsoleListener::IsOpen() | ||
| 79 | { | ||
| 80 | #ifdef _WIN32 | ||
| 81 | return (hConsole != NULL); | ||
| 82 | #else | ||
| 83 | return true; | ||
| 84 | #endif | ||
| 85 | } | ||
| 86 | |||
| 87 | /* | ||
| 88 | LetterSpace: SetConsoleScreenBufferSize and SetConsoleWindowInfo are | ||
| 89 | dependent on each other, that's the reason for the additional checks. | ||
| 90 | */ | ||
| 91 | void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst) | ||
| 92 | { | ||
| 93 | #ifdef _WIN32 | ||
| 94 | BOOL SB, SW; | ||
| 95 | if (BufferFirst) | ||
| 96 | { | ||
| 97 | // Change screen buffer size | ||
| 98 | COORD Co = {BufferWidth, BufferHeight}; | ||
| 99 | SB = SetConsoleScreenBufferSize(hConsole, Co); | ||
| 100 | // Change the screen buffer window size | ||
| 101 | SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom | ||
| 102 | SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); | ||
| 103 | } | ||
| 104 | else | ||
| 105 | { | ||
| 106 | // Change the screen buffer window size | ||
| 107 | SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom | ||
| 108 | SW = SetConsoleWindowInfo(hConsole, TRUE, &coo); | ||
| 109 | // Change screen buffer size | ||
| 110 | COORD Co = {BufferWidth, BufferHeight}; | ||
| 111 | SB = SetConsoleScreenBufferSize(hConsole, Co); | ||
| 112 | } | ||
| 113 | #endif | ||
| 114 | } | ||
| 115 | void ConsoleListener::LetterSpace(int Width, int Height) | ||
| 116 | { | ||
| 117 | #ifdef _WIN32 | ||
| 118 | // Get console info | ||
| 119 | CONSOLE_SCREEN_BUFFER_INFO ConInfo; | ||
| 120 | GetConsoleScreenBufferInfo(hConsole, &ConInfo); | ||
| 121 | |||
| 122 | // | ||
| 123 | int OldBufferWidth = ConInfo.dwSize.X; | ||
| 124 | int OldBufferHeight = ConInfo.dwSize.Y; | ||
| 125 | int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left); | ||
| 126 | int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top); | ||
| 127 | // | ||
| 128 | int NewBufferWidth = Width; | ||
| 129 | int NewBufferHeight = Height; | ||
| 130 | int NewScreenWidth = NewBufferWidth - 1; | ||
| 131 | int NewScreenHeight = OldScreenHeight; | ||
| 132 | |||
| 133 | // Width | ||
| 134 | BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1)); | ||
| 135 | // Height | ||
| 136 | BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1)); | ||
| 137 | |||
| 138 | // Resize the window too | ||
| 139 | //MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true); | ||
| 140 | #endif | ||
| 141 | } | ||
| 142 | #ifdef _WIN32 | ||
| 143 | COORD ConsoleListener::GetCoordinates(int BytesRead, int BufferWidth) | ||
| 144 | { | ||
| 145 | COORD Ret = {0, 0}; | ||
| 146 | // Full rows | ||
| 147 | int Step = (int)floor((float)BytesRead / (float)BufferWidth); | ||
| 148 | Ret.Y += Step; | ||
| 149 | // Partial row | ||
| 150 | Ret.X = BytesRead - (BufferWidth * Step); | ||
| 151 | return Ret; | ||
| 152 | } | ||
| 153 | #endif | ||
| 154 | void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize) | ||
| 155 | { | ||
| 156 | #ifdef _WIN32 | ||
| 157 | // Check size | ||
| 158 | if (Width < 8 || Height < 12) return; | ||
| 159 | |||
| 160 | bool DBef = true; | ||
| 161 | bool DAft = true; | ||
| 162 | std::string SLog = ""; | ||
| 163 | |||
| 164 | const HWND hWnd = GetConsoleWindow(); | ||
| 165 | const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||
| 166 | |||
| 167 | // Get console info | ||
| 168 | CONSOLE_SCREEN_BUFFER_INFO ConInfo; | ||
| 169 | GetConsoleScreenBufferInfo(hConsole, &ConInfo); | ||
| 170 | DWORD BufferSize = ConInfo.dwSize.X * ConInfo.dwSize.Y; | ||
| 171 | |||
| 172 | // --------------------------------------------------------------------- | ||
| 173 | // Save the current text | ||
| 174 | // ------------------------ | ||
| 175 | DWORD cCharsRead = 0; | ||
| 176 | COORD coordScreen = { 0, 0 }; | ||
| 177 | |||
| 178 | static const int MAX_BYTES = 1024 * 16; | ||
| 179 | |||
| 180 | std::vector<std::array<TCHAR, MAX_BYTES>> Str; | ||
| 181 | std::vector<std::array<WORD, MAX_BYTES>> Attr; | ||
| 182 | |||
| 183 | // ReadConsoleOutputAttribute seems to have a limit at this level | ||
| 184 | static const int ReadBufferSize = MAX_BYTES - 32; | ||
| 185 | |||
| 186 | DWORD cAttrRead = ReadBufferSize; | ||
| 187 | DWORD BytesRead = 0; | ||
| 188 | while (BytesRead < BufferSize) | ||
| 189 | { | ||
| 190 | Str.resize(Str.size() + 1); | ||
| 191 | if (!ReadConsoleOutputCharacter(hConsole, Str.back().data(), ReadBufferSize, coordScreen, &cCharsRead)) | ||
| 192 | SLog += Common::StringFromFormat("WriteConsoleOutputCharacter error"); | ||
| 193 | |||
| 194 | Attr.resize(Attr.size() + 1); | ||
| 195 | if (!ReadConsoleOutputAttribute(hConsole, Attr.back().data(), ReadBufferSize, coordScreen, &cAttrRead)) | ||
| 196 | SLog += Common::StringFromFormat("WriteConsoleOutputAttribute error"); | ||
| 197 | |||
| 198 | // Break on error | ||
| 199 | if (cAttrRead == 0) break; | ||
| 200 | BytesRead += cAttrRead; | ||
| 201 | coordScreen = GetCoordinates(BytesRead, ConInfo.dwSize.X); | ||
| 202 | } | ||
| 203 | // Letter space | ||
| 204 | int LWidth = (int)(floor((float)Width / 8.0f) - 1.0f); | ||
| 205 | int LHeight = (int)(floor((float)Height / 12.0f) - 1.0f); | ||
| 206 | int LBufWidth = LWidth + 1; | ||
| 207 | int LBufHeight = (int)floor((float)BufferSize / (float)LBufWidth); | ||
| 208 | // Change screen buffer size | ||
| 209 | LetterSpace(LBufWidth, LBufHeight); | ||
| 210 | |||
| 211 | |||
| 212 | ClearScreen(true); | ||
| 213 | coordScreen.Y = 0; | ||
| 214 | coordScreen.X = 0; | ||
| 215 | DWORD cCharsWritten = 0; | ||
| 216 | |||
| 217 | int BytesWritten = 0; | ||
| 218 | DWORD cAttrWritten = 0; | ||
| 219 | for (size_t i = 0; i < Attr.size(); i++) | ||
| 220 | { | ||
| 221 | if (!WriteConsoleOutputCharacter(hConsole, Str[i].data(), ReadBufferSize, coordScreen, &cCharsWritten)) | ||
| 222 | SLog += Common::StringFromFormat("WriteConsoleOutputCharacter error"); | ||
| 223 | if (!WriteConsoleOutputAttribute(hConsole, Attr[i].data(), ReadBufferSize, coordScreen, &cAttrWritten)) | ||
| 224 | SLog += Common::StringFromFormat("WriteConsoleOutputAttribute error"); | ||
| 225 | |||
| 226 | BytesWritten += cAttrWritten; | ||
| 227 | coordScreen = GetCoordinates(BytesWritten, LBufWidth); | ||
| 228 | } | ||
| 229 | |||
| 230 | const int OldCursor = ConInfo.dwCursorPosition.Y * ConInfo.dwSize.X + ConInfo.dwCursorPosition.X; | ||
| 231 | COORD Coo = GetCoordinates(OldCursor, LBufWidth); | ||
| 232 | SetConsoleCursorPosition(hConsole, Coo); | ||
| 233 | |||
| 234 | if (SLog.length() > 0) Log(LogTypes::LNOTICE, SLog.c_str()); | ||
| 235 | |||
| 236 | // Resize the window too | ||
| 237 | if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 100),Height, true); | ||
| 238 | #endif | ||
| 239 | } | ||
| 240 | |||
| 241 | void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text) | ||
| 242 | { | ||
| 243 | #if defined(_WIN32) | ||
| 244 | WORD Color; | ||
| 245 | |||
| 246 | switch (Level) | ||
| 247 | { | ||
| 248 | case OS_LEVEL: // light yellow | ||
| 249 | Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; | ||
| 250 | break; | ||
| 251 | case NOTICE_LEVEL: // light green | ||
| 252 | Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY; | ||
| 253 | break; | ||
| 254 | case ERROR_LEVEL: // light red | ||
| 255 | Color = FOREGROUND_RED | FOREGROUND_INTENSITY; | ||
| 256 | break; | ||
| 257 | case WARNING_LEVEL: // light purple | ||
| 258 | Color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; | ||
| 259 | break; | ||
| 260 | case INFO_LEVEL: // cyan | ||
| 261 | Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; | ||
| 262 | break; | ||
| 263 | case DEBUG_LEVEL: // gray | ||
| 264 | Color = FOREGROUND_INTENSITY; | ||
| 265 | break; | ||
| 266 | default: // off-white | ||
| 267 | Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; | ||
| 268 | break; | ||
| 269 | } | ||
| 270 | SetConsoleTextAttribute(hConsole, Color); | ||
| 271 | printf(Text); | ||
| 272 | #else | ||
| 273 | char ColorAttr[16] = ""; | ||
| 274 | char ResetAttr[16] = ""; | ||
| 275 | |||
| 276 | if (bUseColor) | ||
| 277 | { | ||
| 278 | strcpy(ResetAttr, "\033[0m"); | ||
| 279 | switch (Level) | ||
| 280 | { | ||
| 281 | case NOTICE_LEVEL: // light green | ||
| 282 | strcpy(ColorAttr, "\033[92m"); | ||
| 283 | break; | ||
| 284 | case ERROR_LEVEL: // light red | ||
| 285 | strcpy(ColorAttr, "\033[91m"); | ||
| 286 | break; | ||
| 287 | case WARNING_LEVEL: // light yellow | ||
| 288 | strcpy(ColorAttr, "\033[93m"); | ||
| 289 | break; | ||
| 290 | default: | ||
| 291 | break; | ||
| 292 | } | ||
| 293 | } | ||
| 294 | fprintf(stderr, "%s%s%s", ColorAttr, Text, ResetAttr); | ||
| 295 | #endif | ||
| 296 | } | ||
| 297 | // Clear console screen | ||
| 298 | void ConsoleListener::ClearScreen(bool Cursor) | ||
| 299 | { | ||
| 300 | #if defined(_WIN32) | ||
| 301 | COORD coordScreen = { 0, 0 }; | ||
| 302 | DWORD cCharsWritten; | ||
| 303 | CONSOLE_SCREEN_BUFFER_INFO csbi; | ||
| 304 | DWORD dwConSize; | ||
| 305 | |||
| 306 | HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | ||
| 307 | |||
| 308 | GetConsoleScreenBufferInfo(hConsole, &csbi); | ||
| 309 | dwConSize = csbi.dwSize.X * csbi.dwSize.Y; | ||
| 310 | // Write space to the entire console | ||
| 311 | FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten); | ||
| 312 | GetConsoleScreenBufferInfo(hConsole, &csbi); | ||
| 313 | FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten); | ||
| 314 | // Reset cursor | ||
| 315 | if (Cursor) SetConsoleCursorPosition(hConsole, coordScreen); | ||
| 316 | #endif | ||
| 317 | } | ||
| 318 | |||
| 319 | |||
diff --git a/src/common/console_listener.h b/src/common/console_listener.h deleted file mode 100644 index ebd90a105..000000000 --- a/src/common/console_listener.h +++ /dev/null | |||
| @@ -1,38 +0,0 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | ||
| 2 | // Licensed under GPLv2 | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/log_manager.h" | ||
| 8 | |||
| 9 | #ifdef _WIN32 | ||
| 10 | #include <windows.h> | ||
| 11 | #endif | ||
| 12 | |||
| 13 | class ConsoleListener : public LogListener | ||
| 14 | { | ||
| 15 | public: | ||
| 16 | ConsoleListener(); | ||
| 17 | ~ConsoleListener(); | ||
| 18 | |||
| 19 | void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console"); | ||
| 20 | void UpdateHandle(); | ||
| 21 | void Close(); | ||
| 22 | bool IsOpen(); | ||
| 23 | void LetterSpace(int Width, int Height); | ||
| 24 | void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst); | ||
| 25 | void PixelSpace(int Left, int Top, int Width, int Height, bool); | ||
| 26 | #ifdef _WIN32 | ||
| 27 | COORD GetCoordinates(int BytesRead, int BufferWidth); | ||
| 28 | #endif | ||
| 29 | void Log(LogTypes::LOG_LEVELS, const char *Text) override; | ||
| 30 | void ClearScreen(bool Cursor = true); | ||
| 31 | |||
| 32 | private: | ||
| 33 | #ifdef _WIN32 | ||
| 34 | HWND GetHwnd(void); | ||
| 35 | HANDLE hConsole; | ||
| 36 | #endif | ||
| 37 | bool bUseColor; | ||
| 38 | }; | ||
diff --git a/src/common/cpu_detect.h b/src/common/cpu_detect.h index def6afdee..b585f9608 100644 --- a/src/common/cpu_detect.h +++ b/src/common/cpu_detect.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | 5 | ||
diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp index 7a2c50ac8..4ec7b263a 100644 --- a/src/common/emu_window.cpp +++ b/src/common/emu_window.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "emu_window.h" | 5 | #include "emu_window.h" |
diff --git a/src/common/emu_window.h b/src/common/emu_window.h index 4cb94fed1..1ad4b82a3 100644 --- a/src/common/emu_window.h +++ b/src/common/emu_window.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/extended_trace.cpp b/src/common/extended_trace.cpp index bf61ac1d1..cf7c346d4 100644 --- a/src/common/extended_trace.cpp +++ b/src/common/extended_trace.cpp | |||
| @@ -82,7 +82,7 @@ static void InitSymbolPath( PSTR lpszSymbolPath, PCSTR lpszIniPath ) | |||
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | // Add user defined path | 84 | // Add user defined path |
| 85 | if ( lpszIniPath != NULL ) | 85 | if ( lpszIniPath != nullptr ) |
| 86 | if ( lpszIniPath[0] != '\0' ) | 86 | if ( lpszIniPath[0] != '\0' ) |
| 87 | { | 87 | { |
| 88 | strcat( lpszSymbolPath, ";" ); | 88 | strcat( lpszSymbolPath, ";" ); |
| @@ -138,7 +138,7 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L | |||
| 138 | DWORD dwSymSize = 10000; | 138 | DWORD dwSymSize = 10000; |
| 139 | TCHAR lpszUnDSymbol[BUFFERSIZE]=_T("?"); | 139 | TCHAR lpszUnDSymbol[BUFFERSIZE]=_T("?"); |
| 140 | CHAR lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?"; | 140 | CHAR lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?"; |
| 141 | LPTSTR lpszParamSep = NULL; | 141 | LPTSTR lpszParamSep = nullptr; |
| 142 | LPTSTR lpszParsed = lpszUnDSymbol; | 142 | LPTSTR lpszParsed = lpszUnDSymbol; |
| 143 | PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize ); | 143 | PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize ); |
| 144 | 144 | ||
| @@ -187,13 +187,13 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L | |||
| 187 | 187 | ||
| 188 | // Let's go through the stack, and modify the function prototype, and insert the actual | 188 | // Let's go through the stack, and modify the function prototype, and insert the actual |
| 189 | // parameter values from the stack | 189 | // parameter values from the stack |
| 190 | if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == NULL && _tcsstr( lpszUnDSymbol, _T("()") ) == NULL) | 190 | if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == nullptr && _tcsstr( lpszUnDSymbol, _T("()") ) == nullptr) |
| 191 | { | 191 | { |
| 192 | ULONG index = 0; | 192 | ULONG index = 0; |
| 193 | for( ; ; index++ ) | 193 | for( ; ; index++ ) |
| 194 | { | 194 | { |
| 195 | lpszParamSep = _tcschr( lpszParsed, _T(',') ); | 195 | lpszParamSep = _tcschr( lpszParsed, _T(',') ); |
| 196 | if ( lpszParamSep == NULL ) | 196 | if ( lpszParamSep == nullptr ) |
| 197 | break; | 197 | break; |
| 198 | 198 | ||
| 199 | *lpszParamSep = _T('\0'); | 199 | *lpszParamSep = _T('\0'); |
| @@ -205,7 +205,7 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L | |||
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | lpszParamSep = _tcschr( lpszParsed, _T(')') ); | 207 | lpszParamSep = _tcschr( lpszParsed, _T(')') ); |
| 208 | if ( lpszParamSep != NULL ) | 208 | if ( lpszParamSep != nullptr ) |
| 209 | { | 209 | { |
| 210 | *lpszParamSep = _T('\0'); | 210 | *lpszParamSep = _T('\0'); |
| 211 | 211 | ||
| @@ -248,7 +248,7 @@ static BOOL GetSourceInfoFromAddress( UINT address, LPTSTR lpszSourceInfo ) | |||
| 248 | PCSTR2LPTSTR( lineInfo.FileName, lpszFileName ); | 248 | PCSTR2LPTSTR( lineInfo.FileName, lpszFileName ); |
| 249 | TCHAR fname[_MAX_FNAME]; | 249 | TCHAR fname[_MAX_FNAME]; |
| 250 | TCHAR ext[_MAX_EXT]; | 250 | TCHAR ext[_MAX_EXT]; |
| 251 | _tsplitpath(lpszFileName, NULL, NULL, fname, ext); | 251 | _tsplitpath(lpszFileName, nullptr, nullptr, fname, ext); |
| 252 | _stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber ); | 252 | _stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber ); |
| 253 | ret = TRUE; | 253 | ret = TRUE; |
| 254 | } | 254 | } |
| @@ -332,11 +332,11 @@ void StackTrace( HANDLE hThread, const char* lpszMessage, FILE *file ) | |||
| 332 | hProcess, | 332 | hProcess, |
| 333 | hThread, | 333 | hThread, |
| 334 | &callStack, | 334 | &callStack, |
| 335 | NULL, | 335 | nullptr, |
| 336 | NULL, | 336 | nullptr, |
| 337 | SymFunctionTableAccess, | 337 | SymFunctionTableAccess, |
| 338 | SymGetModuleBase, | 338 | SymGetModuleBase, |
| 339 | NULL); | 339 | nullptr); |
| 340 | 340 | ||
| 341 | if ( index == 0 ) | 341 | if ( index == 0 ) |
| 342 | continue; | 342 | continue; |
| @@ -389,11 +389,11 @@ void StackTrace(HANDLE hThread, const char* lpszMessage, FILE *file, DWORD eip, | |||
| 389 | hProcess, | 389 | hProcess, |
| 390 | hThread, | 390 | hThread, |
| 391 | &callStack, | 391 | &callStack, |
| 392 | NULL, | 392 | nullptr, |
| 393 | NULL, | 393 | nullptr, |
| 394 | SymFunctionTableAccess, | 394 | SymFunctionTableAccess, |
| 395 | SymGetModuleBase, | 395 | SymGetModuleBase, |
| 396 | NULL); | 396 | nullptr); |
| 397 | 397 | ||
| 398 | if ( index == 0 ) | 398 | if ( index == 0 ) |
| 399 | continue; | 399 | continue; |
diff --git a/src/common/fifo_queue.h b/src/common/fifo_queue.h index 2c18285d4..b426e6596 100644 --- a/src/common/fifo_queue.h +++ b/src/common/fifo_queue.h | |||
| @@ -57,7 +57,7 @@ public: | |||
| 57 | // advance the read pointer | 57 | // advance the read pointer |
| 58 | m_read_ptr = m_read_ptr->next; | 58 | m_read_ptr = m_read_ptr->next; |
| 59 | // set the next element to NULL to stop the recursive deletion | 59 | // set the next element to NULL to stop the recursive deletion |
| 60 | tmpptr->next = NULL; | 60 | tmpptr->next = nullptr; |
| 61 | delete tmpptr; // this also deletes the element | 61 | delete tmpptr; // this also deletes the element |
| 62 | } | 62 | } |
| 63 | 63 | ||
| @@ -86,7 +86,7 @@ private: | |||
| 86 | class ElementPtr | 86 | class ElementPtr |
| 87 | { | 87 | { |
| 88 | public: | 88 | public: |
| 89 | ElementPtr() : current(NULL), next(NULL) {} | 89 | ElementPtr() : current(nullptr), next(nullptr) {} |
| 90 | 90 | ||
| 91 | ~ElementPtr() | 91 | ~ElementPtr() |
| 92 | { | 92 | { |
diff --git a/src/common/file_search.cpp b/src/common/file_search.cpp index bfb54ce72..b3a0a84fb 100644 --- a/src/common/file_search.cpp +++ b/src/common/file_search.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | 5 | ||
diff --git a/src/common/file_search.h b/src/common/file_search.h index f966a008d..55ca02638 100644 --- a/src/common/file_search.h +++ b/src/common/file_search.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index b6dec838c..bba830c70 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | 5 | ||
| @@ -88,7 +88,7 @@ bool IsDirectory(const std::string &filename) | |||
| 88 | #endif | 88 | #endif |
| 89 | 89 | ||
| 90 | if (result < 0) { | 90 | if (result < 0) { |
| 91 | WARN_LOG(COMMON, "IsDirectory: stat failed on %s: %s", | 91 | LOG_WARNING(Common_Filesystem, "stat failed on %s: %s", |
| 92 | filename.c_str(), GetLastErrorMsg()); | 92 | filename.c_str(), GetLastErrorMsg()); |
| 93 | return false; | 93 | return false; |
| 94 | } | 94 | } |
| @@ -100,33 +100,33 @@ bool IsDirectory(const std::string &filename) | |||
| 100 | // Doesn't supports deleting a directory | 100 | // Doesn't supports deleting a directory |
| 101 | bool Delete(const std::string &filename) | 101 | bool Delete(const std::string &filename) |
| 102 | { | 102 | { |
| 103 | INFO_LOG(COMMON, "Delete: file %s", filename.c_str()); | 103 | LOG_INFO(Common_Filesystem, "file %s", filename.c_str()); |
| 104 | 104 | ||
| 105 | // Return true because we care about the file no | 105 | // Return true because we care about the file no |
| 106 | // being there, not the actual delete. | 106 | // being there, not the actual delete. |
| 107 | if (!Exists(filename)) | 107 | if (!Exists(filename)) |
| 108 | { | 108 | { |
| 109 | WARN_LOG(COMMON, "Delete: %s does not exist", filename.c_str()); | 109 | LOG_WARNING(Common_Filesystem, "%s does not exist", filename.c_str()); |
| 110 | return true; | 110 | return true; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | // We can't delete a directory | 113 | // We can't delete a directory |
| 114 | if (IsDirectory(filename)) | 114 | if (IsDirectory(filename)) |
| 115 | { | 115 | { |
| 116 | WARN_LOG(COMMON, "Delete failed: %s is a directory", filename.c_str()); | 116 | LOG_ERROR(Common_Filesystem, "Failed: %s is a directory", filename.c_str()); |
| 117 | return false; | 117 | return false; |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | #ifdef _WIN32 | 120 | #ifdef _WIN32 |
| 121 | if (!DeleteFile(Common::UTF8ToTStr(filename).c_str())) | 121 | if (!DeleteFile(Common::UTF8ToTStr(filename).c_str())) |
| 122 | { | 122 | { |
| 123 | WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s", | 123 | LOG_ERROR(Common_Filesystem, "DeleteFile failed on %s: %s", |
| 124 | filename.c_str(), GetLastErrorMsg()); | 124 | filename.c_str(), GetLastErrorMsg()); |
| 125 | return false; | 125 | return false; |
| 126 | } | 126 | } |
| 127 | #else | 127 | #else |
| 128 | if (unlink(filename.c_str()) == -1) { | 128 | if (unlink(filename.c_str()) == -1) { |
| 129 | WARN_LOG(COMMON, "Delete: unlink failed on %s: %s", | 129 | LOG_ERROR(Common_Filesystem, "unlink failed on %s: %s", |
| 130 | filename.c_str(), GetLastErrorMsg()); | 130 | filename.c_str(), GetLastErrorMsg()); |
| 131 | return false; | 131 | return false; |
| 132 | } | 132 | } |
| @@ -138,17 +138,17 @@ bool Delete(const std::string &filename) | |||
| 138 | // Returns true if successful, or path already exists. | 138 | // Returns true if successful, or path already exists. |
| 139 | bool CreateDir(const std::string &path) | 139 | bool CreateDir(const std::string &path) |
| 140 | { | 140 | { |
| 141 | INFO_LOG(COMMON, "CreateDir: directory %s", path.c_str()); | 141 | LOG_TRACE(Common_Filesystem, "directory %s", path.c_str()); |
| 142 | #ifdef _WIN32 | 142 | #ifdef _WIN32 |
| 143 | if (::CreateDirectory(Common::UTF8ToTStr(path).c_str(), NULL)) | 143 | if (::CreateDirectory(Common::UTF8ToTStr(path).c_str(), nullptr)) |
| 144 | return true; | 144 | return true; |
| 145 | DWORD error = GetLastError(); | 145 | DWORD error = GetLastError(); |
| 146 | if (error == ERROR_ALREADY_EXISTS) | 146 | if (error == ERROR_ALREADY_EXISTS) |
| 147 | { | 147 | { |
| 148 | WARN_LOG(COMMON, "CreateDir: CreateDirectory failed on %s: already exists", path.c_str()); | 148 | LOG_WARNING(Common_Filesystem, "CreateDirectory failed on %s: already exists", path.c_str()); |
| 149 | return true; | 149 | return true; |
| 150 | } | 150 | } |
| 151 | ERROR_LOG(COMMON, "CreateDir: CreateDirectory failed on %s: %i", path.c_str(), error); | 151 | LOG_ERROR(Common_Filesystem, "CreateDirectory failed on %s: %i", path.c_str(), error); |
| 152 | return false; | 152 | return false; |
| 153 | #else | 153 | #else |
| 154 | if (mkdir(path.c_str(), 0755) == 0) | 154 | if (mkdir(path.c_str(), 0755) == 0) |
| @@ -158,11 +158,11 @@ bool CreateDir(const std::string &path) | |||
| 158 | 158 | ||
| 159 | if (err == EEXIST) | 159 | if (err == EEXIST) |
| 160 | { | 160 | { |
| 161 | WARN_LOG(COMMON, "CreateDir: mkdir failed on %s: already exists", path.c_str()); | 161 | LOG_WARNING(Common_Filesystem, "mkdir failed on %s: already exists", path.c_str()); |
| 162 | return true; | 162 | return true; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | ERROR_LOG(COMMON, "CreateDir: mkdir failed on %s: %s", path.c_str(), strerror(err)); | 165 | LOG_ERROR(Common_Filesystem, "mkdir failed on %s: %s", path.c_str(), strerror(err)); |
| 166 | return false; | 166 | return false; |
| 167 | #endif | 167 | #endif |
| 168 | } | 168 | } |
| @@ -171,11 +171,11 @@ bool CreateDir(const std::string &path) | |||
| 171 | bool CreateFullPath(const std::string &fullPath) | 171 | bool CreateFullPath(const std::string &fullPath) |
| 172 | { | 172 | { |
| 173 | int panicCounter = 100; | 173 | int panicCounter = 100; |
| 174 | INFO_LOG(COMMON, "CreateFullPath: path %s", fullPath.c_str()); | 174 | LOG_TRACE(Common_Filesystem, "path %s", fullPath.c_str()); |
| 175 | 175 | ||
| 176 | if (FileUtil::Exists(fullPath)) | 176 | if (FileUtil::Exists(fullPath)) |
| 177 | { | 177 | { |
| 178 | INFO_LOG(COMMON, "CreateFullPath: path exists %s", fullPath.c_str()); | 178 | LOG_WARNING(Common_Filesystem, "path exists %s", fullPath.c_str()); |
| 179 | return true; | 179 | return true; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| @@ -192,7 +192,7 @@ bool CreateFullPath(const std::string &fullPath) | |||
| 192 | // Include the '/' so the first call is CreateDir("/") rather than CreateDir("") | 192 | // Include the '/' so the first call is CreateDir("/") rather than CreateDir("") |
| 193 | std::string const subPath(fullPath.substr(0, position + 1)); | 193 | std::string const subPath(fullPath.substr(0, position + 1)); |
| 194 | if (!FileUtil::IsDirectory(subPath) && !FileUtil::CreateDir(subPath)) { | 194 | if (!FileUtil::IsDirectory(subPath) && !FileUtil::CreateDir(subPath)) { |
| 195 | ERROR_LOG(COMMON, "CreateFullPath: directory creation failed"); | 195 | LOG_ERROR(Common, "CreateFullPath: directory creation failed"); |
| 196 | return false; | 196 | return false; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| @@ -200,7 +200,7 @@ bool CreateFullPath(const std::string &fullPath) | |||
| 200 | panicCounter--; | 200 | panicCounter--; |
| 201 | if (panicCounter <= 0) | 201 | if (panicCounter <= 0) |
| 202 | { | 202 | { |
| 203 | ERROR_LOG(COMMON, "CreateFullPath: directory structure is too deep"); | 203 | LOG_ERROR(Common, "CreateFullPath: directory structure is too deep"); |
| 204 | return false; | 204 | return false; |
| 205 | } | 205 | } |
| 206 | position++; | 206 | position++; |
| @@ -211,12 +211,12 @@ bool CreateFullPath(const std::string &fullPath) | |||
| 211 | // Deletes a directory filename, returns true on success | 211 | // Deletes a directory filename, returns true on success |
| 212 | bool DeleteDir(const std::string &filename) | 212 | bool DeleteDir(const std::string &filename) |
| 213 | { | 213 | { |
| 214 | INFO_LOG(COMMON, "DeleteDir: directory %s", filename.c_str()); | 214 | LOG_INFO(Common_Filesystem, "directory %s", filename.c_str()); |
| 215 | 215 | ||
| 216 | // check if a directory | 216 | // check if a directory |
| 217 | if (!FileUtil::IsDirectory(filename)) | 217 | if (!FileUtil::IsDirectory(filename)) |
| 218 | { | 218 | { |
| 219 | ERROR_LOG(COMMON, "DeleteDir: Not a directory %s", filename.c_str()); | 219 | LOG_ERROR(Common_Filesystem, "Not a directory %s", filename.c_str()); |
| 220 | return false; | 220 | return false; |
| 221 | } | 221 | } |
| 222 | 222 | ||
| @@ -227,7 +227,7 @@ bool DeleteDir(const std::string &filename) | |||
| 227 | if (rmdir(filename.c_str()) == 0) | 227 | if (rmdir(filename.c_str()) == 0) |
| 228 | return true; | 228 | return true; |
| 229 | #endif | 229 | #endif |
| 230 | ERROR_LOG(COMMON, "DeleteDir: %s: %s", filename.c_str(), GetLastErrorMsg()); | 230 | LOG_ERROR(Common_Filesystem, "failed %s: %s", filename.c_str(), GetLastErrorMsg()); |
| 231 | 231 | ||
| 232 | return false; | 232 | return false; |
| 233 | } | 233 | } |
| @@ -235,11 +235,11 @@ bool DeleteDir(const std::string &filename) | |||
| 235 | // renames file srcFilename to destFilename, returns true on success | 235 | // renames file srcFilename to destFilename, returns true on success |
| 236 | bool Rename(const std::string &srcFilename, const std::string &destFilename) | 236 | bool Rename(const std::string &srcFilename, const std::string &destFilename) |
| 237 | { | 237 | { |
| 238 | INFO_LOG(COMMON, "Rename: %s --> %s", | 238 | LOG_TRACE(Common_Filesystem, "%s --> %s", |
| 239 | srcFilename.c_str(), destFilename.c_str()); | 239 | srcFilename.c_str(), destFilename.c_str()); |
| 240 | if (rename(srcFilename.c_str(), destFilename.c_str()) == 0) | 240 | if (rename(srcFilename.c_str(), destFilename.c_str()) == 0) |
| 241 | return true; | 241 | return true; |
| 242 | ERROR_LOG(COMMON, "Rename: failed %s --> %s: %s", | 242 | LOG_ERROR(Common_Filesystem, "failed %s --> %s: %s", |
| 243 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 243 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 244 | return false; | 244 | return false; |
| 245 | } | 245 | } |
| @@ -247,13 +247,13 @@ bool Rename(const std::string &srcFilename, const std::string &destFilename) | |||
| 247 | // copies file srcFilename to destFilename, returns true on success | 247 | // copies file srcFilename to destFilename, returns true on success |
| 248 | bool Copy(const std::string &srcFilename, const std::string &destFilename) | 248 | bool Copy(const std::string &srcFilename, const std::string &destFilename) |
| 249 | { | 249 | { |
| 250 | INFO_LOG(COMMON, "Copy: %s --> %s", | 250 | LOG_TRACE(Common_Filesystem, "%s --> %s", |
| 251 | srcFilename.c_str(), destFilename.c_str()); | 251 | srcFilename.c_str(), destFilename.c_str()); |
| 252 | #ifdef _WIN32 | 252 | #ifdef _WIN32 |
| 253 | if (CopyFile(Common::UTF8ToTStr(srcFilename).c_str(), Common::UTF8ToTStr(destFilename).c_str(), FALSE)) | 253 | if (CopyFile(Common::UTF8ToTStr(srcFilename).c_str(), Common::UTF8ToTStr(destFilename).c_str(), FALSE)) |
| 254 | return true; | 254 | return true; |
| 255 | 255 | ||
| 256 | ERROR_LOG(COMMON, "Copy: failed %s --> %s: %s", | 256 | LOG_ERROR(Common_Filesystem, "failed %s --> %s: %s", |
| 257 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 257 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 258 | return false; | 258 | return false; |
| 259 | #else | 259 | #else |
| @@ -267,7 +267,7 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename) | |||
| 267 | FILE *input = fopen(srcFilename.c_str(), "rb"); | 267 | FILE *input = fopen(srcFilename.c_str(), "rb"); |
| 268 | if (!input) | 268 | if (!input) |
| 269 | { | 269 | { |
| 270 | ERROR_LOG(COMMON, "Copy: input failed %s --> %s: %s", | 270 | LOG_ERROR(Common_Filesystem, "opening input failed %s --> %s: %s", |
| 271 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 271 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 272 | return false; | 272 | return false; |
| 273 | } | 273 | } |
| @@ -277,7 +277,7 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename) | |||
| 277 | if (!output) | 277 | if (!output) |
| 278 | { | 278 | { |
| 279 | fclose(input); | 279 | fclose(input); |
| 280 | ERROR_LOG(COMMON, "Copy: output failed %s --> %s: %s", | 280 | LOG_ERROR(Common_Filesystem, "opening output failed %s --> %s: %s", |
| 281 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 281 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 282 | return false; | 282 | return false; |
| 283 | } | 283 | } |
| @@ -291,8 +291,8 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename) | |||
| 291 | { | 291 | { |
| 292 | if (ferror(input) != 0) | 292 | if (ferror(input) != 0) |
| 293 | { | 293 | { |
| 294 | ERROR_LOG(COMMON, | 294 | LOG_ERROR(Common_Filesystem, |
| 295 | "Copy: failed reading from source, %s --> %s: %s", | 295 | "failed reading from source, %s --> %s: %s", |
| 296 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 296 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 297 | goto bail; | 297 | goto bail; |
| 298 | } | 298 | } |
| @@ -302,8 +302,8 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename) | |||
| 302 | int wnum = fwrite(buffer, sizeof(char), rnum, output); | 302 | int wnum = fwrite(buffer, sizeof(char), rnum, output); |
| 303 | if (wnum != rnum) | 303 | if (wnum != rnum) |
| 304 | { | 304 | { |
| 305 | ERROR_LOG(COMMON, | 305 | LOG_ERROR(Common_Filesystem, |
| 306 | "Copy: failed writing to output, %s --> %s: %s", | 306 | "failed writing to output, %s --> %s: %s", |
| 307 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 307 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 308 | goto bail; | 308 | goto bail; |
| 309 | } | 309 | } |
| @@ -326,13 +326,13 @@ u64 GetSize(const std::string &filename) | |||
| 326 | { | 326 | { |
| 327 | if (!Exists(filename)) | 327 | if (!Exists(filename)) |
| 328 | { | 328 | { |
| 329 | WARN_LOG(COMMON, "GetSize: failed %s: No such file", filename.c_str()); | 329 | LOG_ERROR(Common_Filesystem, "failed %s: No such file", filename.c_str()); |
| 330 | return 0; | 330 | return 0; |
| 331 | } | 331 | } |
| 332 | 332 | ||
| 333 | if (IsDirectory(filename)) | 333 | if (IsDirectory(filename)) |
| 334 | { | 334 | { |
| 335 | WARN_LOG(COMMON, "GetSize: failed %s: is a directory", filename.c_str()); | 335 | LOG_ERROR(Common_Filesystem, "failed %s: is a directory", filename.c_str()); |
| 336 | return 0; | 336 | return 0; |
| 337 | } | 337 | } |
| 338 | 338 | ||
| @@ -343,12 +343,12 @@ u64 GetSize(const std::string &filename) | |||
| 343 | if (stat64(filename.c_str(), &buf) == 0) | 343 | if (stat64(filename.c_str(), &buf) == 0) |
| 344 | #endif | 344 | #endif |
| 345 | { | 345 | { |
| 346 | DEBUG_LOG(COMMON, "GetSize: %s: %lld", | 346 | LOG_TRACE(Common_Filesystem, "%s: %lld", |
| 347 | filename.c_str(), (long long)buf.st_size); | 347 | filename.c_str(), (long long)buf.st_size); |
| 348 | return buf.st_size; | 348 | return buf.st_size; |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | ERROR_LOG(COMMON, "GetSize: Stat failed %s: %s", | 351 | LOG_ERROR(Common_Filesystem, "Stat failed %s: %s", |
| 352 | filename.c_str(), GetLastErrorMsg()); | 352 | filename.c_str(), GetLastErrorMsg()); |
| 353 | return 0; | 353 | return 0; |
| 354 | } | 354 | } |
| @@ -358,7 +358,7 @@ u64 GetSize(const int fd) | |||
| 358 | { | 358 | { |
| 359 | struct stat64 buf; | 359 | struct stat64 buf; |
| 360 | if (fstat64(fd, &buf) != 0) { | 360 | if (fstat64(fd, &buf) != 0) { |
| 361 | ERROR_LOG(COMMON, "GetSize: stat failed %i: %s", | 361 | LOG_ERROR(Common_Filesystem, "GetSize: stat failed %i: %s", |
| 362 | fd, GetLastErrorMsg()); | 362 | fd, GetLastErrorMsg()); |
| 363 | return 0; | 363 | return 0; |
| 364 | } | 364 | } |
| @@ -371,13 +371,13 @@ u64 GetSize(FILE *f) | |||
| 371 | // can't use off_t here because it can be 32-bit | 371 | // can't use off_t here because it can be 32-bit |
| 372 | u64 pos = ftello(f); | 372 | u64 pos = ftello(f); |
| 373 | if (fseeko(f, 0, SEEK_END) != 0) { | 373 | if (fseeko(f, 0, SEEK_END) != 0) { |
| 374 | ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", | 374 | LOG_ERROR(Common_Filesystem, "GetSize: seek failed %p: %s", |
| 375 | f, GetLastErrorMsg()); | 375 | f, GetLastErrorMsg()); |
| 376 | return 0; | 376 | return 0; |
| 377 | } | 377 | } |
| 378 | u64 size = ftello(f); | 378 | u64 size = ftello(f); |
| 379 | if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) { | 379 | if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) { |
| 380 | ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", | 380 | LOG_ERROR(Common_Filesystem, "GetSize: seek failed %p: %s", |
| 381 | f, GetLastErrorMsg()); | 381 | f, GetLastErrorMsg()); |
| 382 | return 0; | 382 | return 0; |
| 383 | } | 383 | } |
| @@ -387,11 +387,11 @@ u64 GetSize(FILE *f) | |||
| 387 | // creates an empty file filename, returns true on success | 387 | // creates an empty file filename, returns true on success |
| 388 | bool CreateEmptyFile(const std::string &filename) | 388 | bool CreateEmptyFile(const std::string &filename) |
| 389 | { | 389 | { |
| 390 | INFO_LOG(COMMON, "CreateEmptyFile: %s", filename.c_str()); | 390 | LOG_TRACE(Common_Filesystem, "%s", filename.c_str()); |
| 391 | 391 | ||
| 392 | if (!FileUtil::IOFile(filename, "wb")) | 392 | if (!FileUtil::IOFile(filename, "wb")) |
| 393 | { | 393 | { |
| 394 | ERROR_LOG(COMMON, "CreateEmptyFile: failed %s: %s", | 394 | LOG_ERROR(Common_Filesystem, "failed %s: %s", |
| 395 | filename.c_str(), GetLastErrorMsg()); | 395 | filename.c_str(), GetLastErrorMsg()); |
| 396 | return false; | 396 | return false; |
| 397 | } | 397 | } |
| @@ -404,7 +404,7 @@ bool CreateEmptyFile(const std::string &filename) | |||
| 404 | // results into parentEntry. Returns the number of files+directories found | 404 | // results into parentEntry. Returns the number of files+directories found |
| 405 | u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) | 405 | u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) |
| 406 | { | 406 | { |
| 407 | INFO_LOG(COMMON, "ScanDirectoryTree: directory %s", directory.c_str()); | 407 | LOG_TRACE(Common_Filesystem, "directory %s", directory.c_str()); |
| 408 | // How many files + directories we found | 408 | // How many files + directories we found |
| 409 | u32 foundEntries = 0; | 409 | u32 foundEntries = 0; |
| 410 | #ifdef _WIN32 | 410 | #ifdef _WIN32 |
| @@ -423,7 +423,7 @@ u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) | |||
| 423 | FSTEntry entry; | 423 | FSTEntry entry; |
| 424 | const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); | 424 | const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); |
| 425 | #else | 425 | #else |
| 426 | struct dirent dirent, *result = NULL; | 426 | struct dirent dirent, *result = nullptr; |
| 427 | 427 | ||
| 428 | DIR *dirp = opendir(directory.c_str()); | 428 | DIR *dirp = opendir(directory.c_str()); |
| 429 | if (!dirp) | 429 | if (!dirp) |
| @@ -474,7 +474,7 @@ u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) | |||
| 474 | // Deletes the given directory and anything under it. Returns true on success. | 474 | // Deletes the given directory and anything under it. Returns true on success. |
| 475 | bool DeleteDirRecursively(const std::string &directory) | 475 | bool DeleteDirRecursively(const std::string &directory) |
| 476 | { | 476 | { |
| 477 | INFO_LOG(COMMON, "DeleteDirRecursively: %s", directory.c_str()); | 477 | LOG_TRACE(Common_Filesystem, "%s", directory.c_str()); |
| 478 | #ifdef _WIN32 | 478 | #ifdef _WIN32 |
| 479 | // Find the first file in the directory. | 479 | // Find the first file in the directory. |
| 480 | WIN32_FIND_DATA ffd; | 480 | WIN32_FIND_DATA ffd; |
| @@ -491,7 +491,7 @@ bool DeleteDirRecursively(const std::string &directory) | |||
| 491 | { | 491 | { |
| 492 | const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); | 492 | const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); |
| 493 | #else | 493 | #else |
| 494 | struct dirent dirent, *result = NULL; | 494 | struct dirent dirent, *result = nullptr; |
| 495 | DIR *dirp = opendir(directory.c_str()); | 495 | DIR *dirp = opendir(directory.c_str()); |
| 496 | if (!dirp) | 496 | if (!dirp) |
| 497 | return false; | 497 | return false; |
| @@ -552,7 +552,7 @@ void CopyDir(const std::string &source_path, const std::string &dest_path) | |||
| 552 | if (!FileUtil::Exists(source_path)) return; | 552 | if (!FileUtil::Exists(source_path)) return; |
| 553 | if (!FileUtil::Exists(dest_path)) FileUtil::CreateFullPath(dest_path); | 553 | if (!FileUtil::Exists(dest_path)) FileUtil::CreateFullPath(dest_path); |
| 554 | 554 | ||
| 555 | struct dirent dirent, *result = NULL; | 555 | struct dirent dirent, *result = nullptr; |
| 556 | DIR *dirp = opendir(source_path.c_str()); | 556 | DIR *dirp = opendir(source_path.c_str()); |
| 557 | if (!dirp) return; | 557 | if (!dirp) return; |
| 558 | 558 | ||
| @@ -586,11 +586,11 @@ std::string GetCurrentDir() | |||
| 586 | { | 586 | { |
| 587 | char *dir; | 587 | char *dir; |
| 588 | // Get the current working directory (getcwd uses malloc) | 588 | // Get the current working directory (getcwd uses malloc) |
| 589 | if (!(dir = __getcwd(NULL, 0))) { | 589 | if (!(dir = __getcwd(nullptr, 0))) { |
| 590 | 590 | ||
| 591 | ERROR_LOG(COMMON, "GetCurrentDirectory failed: %s", | 591 | LOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: %s", |
| 592 | GetLastErrorMsg()); | 592 | GetLastErrorMsg()); |
| 593 | return NULL; | 593 | return nullptr; |
| 594 | } | 594 | } |
| 595 | std::string strDir = dir; | 595 | std::string strDir = dir; |
| 596 | free(dir); | 596 | free(dir); |
| @@ -626,7 +626,7 @@ std::string& GetExeDirectory() | |||
| 626 | if (DolphinPath.empty()) | 626 | if (DolphinPath.empty()) |
| 627 | { | 627 | { |
| 628 | TCHAR Dolphin_exe_Path[2048]; | 628 | TCHAR Dolphin_exe_Path[2048]; |
| 629 | GetModuleFileName(NULL, Dolphin_exe_Path, 2048); | 629 | GetModuleFileName(nullptr, Dolphin_exe_Path, 2048); |
| 630 | DolphinPath = Common::TStrToUTF8(Dolphin_exe_Path); | 630 | DolphinPath = Common::TStrToUTF8(Dolphin_exe_Path); |
| 631 | DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\')); | 631 | DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\')); |
| 632 | } | 632 | } |
| @@ -647,7 +647,7 @@ std::string GetSysDirectory() | |||
| 647 | #endif | 647 | #endif |
| 648 | sysDir += DIR_SEP; | 648 | sysDir += DIR_SEP; |
| 649 | 649 | ||
| 650 | INFO_LOG(COMMON, "GetSysDirectory: Setting to %s:", sysDir.c_str()); | 650 | LOG_DEBUG(Common_Filesystem, "Setting to %s:", sysDir.c_str()); |
| 651 | return sysDir; | 651 | return sysDir; |
| 652 | } | 652 | } |
| 653 | 653 | ||
| @@ -676,6 +676,9 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new | |||
| 676 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; | 676 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; |
| 677 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; | 677 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; |
| 678 | paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; | 678 | paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; |
| 679 | paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; | ||
| 680 | paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; | ||
| 681 | paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP; | ||
| 679 | 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; |
| 680 | 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; |
| 681 | 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; |
| @@ -694,7 +697,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new | |||
| 694 | { | 697 | { |
| 695 | if (!FileUtil::IsDirectory(newPath)) | 698 | if (!FileUtil::IsDirectory(newPath)) |
| 696 | { | 699 | { |
| 697 | WARN_LOG(COMMON, "Invalid path specified %s", newPath.c_str()); | 700 | LOG_ERROR(Common_Filesystem, "Invalid path specified %s", newPath.c_str()); |
| 698 | return paths[DirIDX]; | 701 | return paths[DirIDX]; |
| 699 | } | 702 | } |
| 700 | else | 703 | else |
| @@ -717,6 +720,8 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new | |||
| 717 | 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; |
| 718 | 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; |
| 719 | paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; | 722 | paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; |
| 723 | paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; | ||
| 724 | paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP; | ||
| 720 | paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; | 725 | paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; |
| 721 | paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; | 726 | paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; |
| 722 | paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; | 727 | paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; |
| @@ -753,19 +758,6 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new | |||
| 753 | return paths[DirIDX]; | 758 | return paths[DirIDX]; |
| 754 | } | 759 | } |
| 755 | 760 | ||
| 756 | //std::string GetThemeDir(const std::string& theme_name) | ||
| 757 | //{ | ||
| 758 | // std::string dir = FileUtil::GetUserPath(D_THEMES_IDX) + theme_name + "/"; | ||
| 759 | // | ||
| 760 | //#if !defined(_WIN32) | ||
| 761 | // // If theme does not exist in user's dir load from shared directory | ||
| 762 | // if (!FileUtil::Exists(dir)) | ||
| 763 | // dir = SHARED_USER_DIR THEMES_DIR "/" + theme_name + "/"; | ||
| 764 | //#endif | ||
| 765 | // | ||
| 766 | // return dir; | ||
| 767 | //} | ||
| 768 | |||
| 769 | size_t WriteStringToFile(bool text_file, const std::string &str, const char *filename) | 761 | size_t WriteStringToFile(bool text_file, const std::string &str, const char *filename) |
| 770 | { | 762 | { |
| 771 | return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); | 763 | return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); |
| @@ -826,7 +818,7 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam | |||
| 826 | } | 818 | } |
| 827 | 819 | ||
| 828 | IOFile::IOFile() | 820 | IOFile::IOFile() |
| 829 | : m_file(NULL), m_good(true) | 821 | : m_file(nullptr), m_good(true) |
| 830 | {} | 822 | {} |
| 831 | 823 | ||
| 832 | IOFile::IOFile(std::FILE* file) | 824 | IOFile::IOFile(std::FILE* file) |
| @@ -834,7 +826,7 @@ IOFile::IOFile(std::FILE* file) | |||
| 834 | {} | 826 | {} |
| 835 | 827 | ||
| 836 | IOFile::IOFile(const std::string& filename, const char openmode[]) | 828 | IOFile::IOFile(const std::string& filename, const char openmode[]) |
| 837 | : m_file(NULL), m_good(true) | 829 | : m_file(nullptr), m_good(true) |
| 838 | { | 830 | { |
| 839 | Open(filename, openmode); | 831 | Open(filename, openmode); |
| 840 | } | 832 | } |
| @@ -845,7 +837,7 @@ IOFile::~IOFile() | |||
| 845 | } | 837 | } |
| 846 | 838 | ||
| 847 | IOFile::IOFile(IOFile&& other) | 839 | IOFile::IOFile(IOFile&& other) |
| 848 | : m_file(NULL), m_good(true) | 840 | : m_file(nullptr), m_good(true) |
| 849 | { | 841 | { |
| 850 | Swap(other); | 842 | Swap(other); |
| 851 | } | 843 | } |
| @@ -880,14 +872,14 @@ bool IOFile::Close() | |||
| 880 | if (!IsOpen() || 0 != std::fclose(m_file)) | 872 | if (!IsOpen() || 0 != std::fclose(m_file)) |
| 881 | m_good = false; | 873 | m_good = false; |
| 882 | 874 | ||
| 883 | m_file = NULL; | 875 | m_file = nullptr; |
| 884 | return m_good; | 876 | return m_good; |
| 885 | } | 877 | } |
| 886 | 878 | ||
| 887 | std::FILE* IOFile::ReleaseHandle() | 879 | std::FILE* IOFile::ReleaseHandle() |
| 888 | { | 880 | { |
| 889 | std::FILE* const ret = m_file; | 881 | std::FILE* const ret = m_file; |
| 890 | m_file = NULL; | 882 | m_file = nullptr; |
| 891 | return ret; | 883 | return ret; |
| 892 | } | 884 | } |
| 893 | 885 | ||
diff --git a/src/common/file_util.h b/src/common/file_util.h index 72b80be8a..293c30941 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| @@ -27,6 +27,9 @@ enum { | |||
| 27 | D_STATESAVES_IDX, | 27 | D_STATESAVES_IDX, |
| 28 | D_SCREENSHOTS_IDX, | 28 | D_SCREENSHOTS_IDX, |
| 29 | D_SDMC_IDX, | 29 | D_SDMC_IDX, |
| 30 | D_SAVEDATA_IDX, | ||
| 31 | D_SYSDATA_IDX, | ||
| 32 | D_SYSSAVEDATA_IDX, | ||
| 30 | D_HIRESTEXTURES_IDX, | 33 | D_HIRESTEXTURES_IDX, |
| 31 | D_DUMP_IDX, | 34 | D_DUMP_IDX, |
| 32 | D_DUMPFRAMES_IDX, | 35 | D_DUMPFRAMES_IDX, |
| @@ -202,11 +205,11 @@ public: | |||
| 202 | return WriteArray(reinterpret_cast<const char*>(data), length); | 205 | return WriteArray(reinterpret_cast<const char*>(data), length); |
| 203 | } | 206 | } |
| 204 | 207 | ||
| 205 | bool IsOpen() { return NULL != m_file; } | 208 | bool IsOpen() { return nullptr != m_file; } |
| 206 | 209 | ||
| 207 | // m_good is set to false when a read, write or other function fails | 210 | // m_good is set to false when a read, write or other function fails |
| 208 | bool IsGood() { return m_good; } | 211 | bool IsGood() { return m_good; } |
| 209 | operator void*() { return m_good ? m_file : NULL; } | 212 | operator void*() { return m_good ? m_file : nullptr; } |
| 210 | 213 | ||
| 211 | std::FILE* ReleaseHandle(); | 214 | std::FILE* ReleaseHandle(); |
| 212 | 215 | ||
diff --git a/src/common/hash.cpp b/src/common/hash.cpp index 2ddcfe6b7..fe2c9e636 100644 --- a/src/common/hash.cpp +++ b/src/common/hash.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | 5 | ||
diff --git a/src/common/hash.h b/src/common/hash.h index 29f699d7f..3ac42bc44 100644 --- a/src/common/hash.h +++ b/src/common/hash.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/key_map.cpp b/src/common/key_map.cpp index 309caab98..d8945bb13 100644 --- a/src/common/key_map.cpp +++ b/src/common/key_map.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "key_map.h" | 5 | #include "key_map.h" |
diff --git a/src/common/key_map.h b/src/common/key_map.h index bf72362c0..8d949b852 100644 --- a/src/common/key_map.h +++ b/src/common/key_map.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/linear_disk_cache.h b/src/common/linear_disk_cache.h index f4263f72a..74ce74aba 100644 --- a/src/common/linear_disk_cache.h +++ b/src/common/linear_disk_cache.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| @@ -70,7 +70,7 @@ public: | |||
| 70 | // good header, read some key/value pairs | 70 | // good header, read some key/value pairs |
| 71 | K key; | 71 | K key; |
| 72 | 72 | ||
| 73 | V *value = NULL; | 73 | V *value = nullptr; |
| 74 | u32 value_size; | 74 | u32 value_size; |
| 75 | u32 entry_number; | 75 | u32 entry_number; |
| 76 | 76 | ||
diff --git a/src/common/log.h b/src/common/log.h index 4c96ef0a6..c6a023552 100644 --- a/src/common/log.h +++ b/src/common/log.h | |||
| @@ -1,108 +1,12 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #ifndef LOGGING | 7 | #include "common/common_funcs.h" |
| 8 | #define LOGGING | 8 | #include "common/msg_handler.h" |
| 9 | #endif | 9 | #include "common/logging/log.h" |
| 10 | |||
| 11 | enum { | ||
| 12 | OS_LEVEL, // Printed by the emulated operating system | ||
| 13 | NOTICE_LEVEL, // VERY important information that is NOT errors. Like startup and OSReports. | ||
| 14 | ERROR_LEVEL, // Critical errors | ||
| 15 | WARNING_LEVEL, // Something is suspicious. | ||
| 16 | INFO_LEVEL, // General information. | ||
| 17 | DEBUG_LEVEL, // Detailed debugging - might make things slow. | ||
| 18 | }; | ||
| 19 | |||
| 20 | namespace LogTypes | ||
| 21 | { | ||
| 22 | |||
| 23 | enum LOG_TYPE { | ||
| 24 | ACTIONREPLAY, | ||
| 25 | AUDIO, | ||
| 26 | AUDIO_INTERFACE, | ||
| 27 | BOOT, | ||
| 28 | COMMANDPROCESSOR, | ||
| 29 | COMMON, | ||
| 30 | CONSOLE, | ||
| 31 | CONFIG, | ||
| 32 | DISCIO, | ||
| 33 | FILEMON, | ||
| 34 | DSPHLE, | ||
| 35 | DSPLLE, | ||
| 36 | DSP_MAIL, | ||
| 37 | DSPINTERFACE, | ||
| 38 | DVDINTERFACE, | ||
| 39 | DYNA_REC, | ||
| 40 | EXPANSIONINTERFACE, | ||
| 41 | GDB_STUB, | ||
| 42 | ARM11, | ||
| 43 | GSP, | ||
| 44 | OSHLE, | ||
| 45 | MASTER_LOG, | ||
| 46 | MEMMAP, | ||
| 47 | MEMCARD_MANAGER, | ||
| 48 | OSREPORT, | ||
| 49 | PAD, | ||
| 50 | PROCESSORINTERFACE, | ||
| 51 | PIXELENGINE, | ||
| 52 | SERIALINTERFACE, | ||
| 53 | SP1, | ||
| 54 | STREAMINGINTERFACE, | ||
| 55 | VIDEO, | ||
| 56 | VIDEOINTERFACE, | ||
| 57 | LOADER, | ||
| 58 | FILESYS, | ||
| 59 | WII_IPC_DVD, | ||
| 60 | WII_IPC_ES, | ||
| 61 | WII_IPC_FILEIO, | ||
| 62 | WII_IPC_HID, | ||
| 63 | KERNEL, | ||
| 64 | SVC, | ||
| 65 | NDMA, | ||
| 66 | HLE, | ||
| 67 | RENDER, | ||
| 68 | GPU, | ||
| 69 | HW, | ||
| 70 | TIME, | ||
| 71 | NETPLAY, | ||
| 72 | GUI, | ||
| 73 | |||
| 74 | NUMBER_OF_LOGS // Must be last | ||
| 75 | }; | ||
| 76 | |||
| 77 | // FIXME: should this be removed? | ||
| 78 | enum LOG_LEVELS { | ||
| 79 | LOS = OS_LEVEL, | ||
| 80 | LNOTICE = NOTICE_LEVEL, | ||
| 81 | LERROR = ERROR_LEVEL, | ||
| 82 | LWARNING = WARNING_LEVEL, | ||
| 83 | LINFO = INFO_LEVEL, | ||
| 84 | LDEBUG = DEBUG_LEVEL, | ||
| 85 | }; | ||
| 86 | |||
| 87 | #define LOGTYPES_LEVELS LogTypes::LOG_LEVELS | ||
| 88 | #define LOGTYPES_TYPE LogTypes::LOG_TYPE | ||
| 89 | |||
| 90 | } // namespace | ||
| 91 | |||
| 92 | void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, const char*file, int line, | ||
| 93 | const char* function, const char* fmt, ...) | ||
| 94 | #ifdef __GNUC__ | ||
| 95 | __attribute__((format(printf, 6, 7))) | ||
| 96 | #endif | ||
| 97 | ; | ||
| 98 | |||
| 99 | #if defined LOGGING || defined _DEBUG || defined DEBUGFAST | ||
| 100 | #define MAX_LOGLEVEL LDEBUG | ||
| 101 | #else | ||
| 102 | #ifndef MAX_LOGLEVEL | ||
| 103 | #define MAX_LOGLEVEL LWARNING | ||
| 104 | #endif // loglevel | ||
| 105 | #endif // logging | ||
| 106 | 10 | ||
| 107 | #ifdef MSVC_VER | 11 | #ifdef MSVC_VER |
| 108 | #ifndef __func__ | 12 | #ifndef __func__ |
| @@ -110,29 +14,16 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, const char*file, int | |||
| 110 | #endif | 14 | #endif |
| 111 | #endif | 15 | #endif |
| 112 | 16 | ||
| 113 | // Let the compiler optimize this out | 17 | #if _DEBUG |
| 114 | #define GENERIC_LOG(t, v, ...) { \ | ||
| 115 | if (v <= LogTypes::MAX_LOGLEVEL) \ | ||
| 116 | GenericLog(v, t, __FILE__, __LINE__, __func__, __VA_ARGS__); \ | ||
| 117 | } | ||
| 118 | |||
| 119 | #define OS_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LOS, __VA_ARGS__) } while (0) | ||
| 120 | #define ERROR_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LERROR, __VA_ARGS__) } while (0) | ||
| 121 | #define WARN_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LWARNING, __VA_ARGS__) } while (0) | ||
| 122 | #define NOTICE_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LNOTICE, __VA_ARGS__) } while (0) | ||
| 123 | #define INFO_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LINFO, __VA_ARGS__) } while (0) | ||
| 124 | #define DEBUG_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LDEBUG, __VA_ARGS__) } while (0) | ||
| 125 | |||
| 126 | #if MAX_LOGLEVEL >= DEBUG_LEVEL | ||
| 127 | #define _dbg_assert_(_t_, _a_) \ | 18 | #define _dbg_assert_(_t_, _a_) \ |
| 128 | if (!(_a_)) {\ | 19 | if (!(_a_)) {\ |
| 129 | ERROR_LOG(_t_, "Error...\n\n Line: %d\n File: %s\n Time: %s\n\nIgnore and continue?", \ | 20 | LOG_CRITICAL(_t_, "Error...\n\n Line: %d\n File: %s\n Time: %s\n\nIgnore and continue?", \ |
| 130 | __LINE__, __FILE__, __TIME__); \ | 21 | __LINE__, __FILE__, __TIME__); \ |
| 131 | if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \ | 22 | if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \ |
| 132 | } | 23 | } |
| 133 | #define _dbg_assert_msg_(_t_, _a_, ...)\ | 24 | #define _dbg_assert_msg_(_t_, _a_, ...)\ |
| 134 | if (!(_a_)) {\ | 25 | if (!(_a_)) {\ |
| 135 | ERROR_LOG(_t_, __VA_ARGS__); \ | 26 | LOG_CRITICAL(_t_, __VA_ARGS__); \ |
| 136 | if (!PanicYesNo(__VA_ARGS__)) {Crash();} \ | 27 | if (!PanicYesNo(__VA_ARGS__)) {Crash();} \ |
| 137 | } | 28 | } |
| 138 | #define _dbg_update_() Host_UpdateLogDisplay(); | 29 | #define _dbg_update_() Host_UpdateLogDisplay(); |
| @@ -144,12 +35,12 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, const char*file, int | |||
| 144 | #define _dbg_assert_(_t_, _a_) {} | 35 | #define _dbg_assert_(_t_, _a_) {} |
| 145 | #define _dbg_assert_msg_(_t_, _a_, _desc_, ...) {} | 36 | #define _dbg_assert_msg_(_t_, _a_, _desc_, ...) {} |
| 146 | #endif // dbg_assert | 37 | #endif // dbg_assert |
| 147 | #endif // MAX_LOGLEVEL DEBUG | 38 | #endif |
| 148 | 39 | ||
| 149 | #define _assert_(_a_) _dbg_assert_(MASTER_LOG, _a_) | 40 | #define _assert_(_a_) _dbg_assert_(MASTER_LOG, _a_) |
| 150 | 41 | ||
| 151 | #ifndef GEKKO | 42 | #ifndef GEKKO |
| 152 | #ifdef MSVC_VER | 43 | #ifdef _WIN32 |
| 153 | #define _assert_msg_(_t_, _a_, _fmt_, ...) \ | 44 | #define _assert_msg_(_t_, _a_, _fmt_, ...) \ |
| 154 | if (!(_a_)) {\ | 45 | if (!(_a_)) {\ |
| 155 | if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \ | 46 | if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \ |
| @@ -159,7 +50,7 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, const char*file, int | |||
| 159 | if (!(_a_)) {\ | 50 | if (!(_a_)) {\ |
| 160 | if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \ | 51 | if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \ |
| 161 | } | 52 | } |
| 162 | #endif // MSVC_VER | 53 | #endif // _WIN32 |
| 163 | #else // GEKKO | 54 | #else // GEKKO |
| 164 | #define _assert_msg_(_t_, _a_, _fmt_, ...) | 55 | #define _assert_msg_(_t_, _a_, _fmt_, ...) |
| 165 | #endif | 56 | #endif \ No newline at end of file |
diff --git a/src/common/log_manager.cpp b/src/common/log_manager.cpp deleted file mode 100644 index 2ef7d98c0..000000000 --- a/src/common/log_manager.cpp +++ /dev/null | |||
| @@ -1,199 +0,0 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | ||
| 2 | // Licensed under GPLv2 | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | |||
| 7 | #include "common/log_manager.h" | ||
| 8 | #include "common/console_listener.h" | ||
| 9 | #include "common/timer.h" | ||
| 10 | |||
| 11 | void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line, | ||
| 12 | const char* function, const char* fmt, ...) | ||
| 13 | { | ||
| 14 | va_list args; | ||
| 15 | va_start(args, fmt); | ||
| 16 | |||
| 17 | if (LogManager::GetInstance()) { | ||
| 18 | LogManager::GetInstance()->Log(level, type, | ||
| 19 | file, line, function, fmt, args); | ||
| 20 | } | ||
| 21 | va_end(args); | ||
| 22 | } | ||
| 23 | |||
| 24 | LogManager *LogManager::m_logManager = NULL; | ||
| 25 | |||
| 26 | LogManager::LogManager() | ||
| 27 | { | ||
| 28 | // create log files | ||
| 29 | m_Log[LogTypes::MASTER_LOG] = new LogContainer("*", "Master Log"); | ||
| 30 | m_Log[LogTypes::BOOT] = new LogContainer("BOOT", "Boot"); | ||
| 31 | m_Log[LogTypes::COMMON] = new LogContainer("COMMON", "Common"); | ||
| 32 | m_Log[LogTypes::CONFIG] = new LogContainer("CONFIG", "Configuration"); | ||
| 33 | m_Log[LogTypes::DISCIO] = new LogContainer("DIO", "Disc IO"); | ||
| 34 | m_Log[LogTypes::FILEMON] = new LogContainer("FileMon", "File Monitor"); | ||
| 35 | m_Log[LogTypes::PAD] = new LogContainer("PAD", "Pad"); | ||
| 36 | m_Log[LogTypes::PIXELENGINE] = new LogContainer("PE", "PixelEngine"); | ||
| 37 | m_Log[LogTypes::COMMANDPROCESSOR] = new LogContainer("CP", "CommandProc"); | ||
| 38 | m_Log[LogTypes::VIDEOINTERFACE] = new LogContainer("VI", "VideoInt"); | ||
| 39 | m_Log[LogTypes::SERIALINTERFACE] = new LogContainer("SI", "SerialInt"); | ||
| 40 | m_Log[LogTypes::PROCESSORINTERFACE] = new LogContainer("PI", "ProcessorInt"); | ||
| 41 | m_Log[LogTypes::MEMMAP] = new LogContainer("MI", "MI & memmap"); | ||
| 42 | m_Log[LogTypes::SP1] = new LogContainer("SP1", "Serial Port 1"); | ||
| 43 | m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream", "StreamingInt"); | ||
| 44 | m_Log[LogTypes::DSPINTERFACE] = new LogContainer("DSP", "DSPInterface"); | ||
| 45 | m_Log[LogTypes::DVDINTERFACE] = new LogContainer("DVD", "DVDInterface"); | ||
| 46 | m_Log[LogTypes::GSP] = new LogContainer("GSP", "GSP"); | ||
| 47 | m_Log[LogTypes::EXPANSIONINTERFACE] = new LogContainer("EXI", "ExpansionInt"); | ||
| 48 | m_Log[LogTypes::GDB_STUB] = new LogContainer("GDB_STUB", "GDB Stub"); | ||
| 49 | m_Log[LogTypes::AUDIO_INTERFACE] = new LogContainer("AI", "AudioInt"); | ||
| 50 | m_Log[LogTypes::ARM11] = new LogContainer("ARM11", "ARM11"); | ||
| 51 | m_Log[LogTypes::OSHLE] = new LogContainer("HLE", "HLE"); | ||
| 52 | m_Log[LogTypes::DSPHLE] = new LogContainer("DSPHLE", "DSP HLE"); | ||
| 53 | m_Log[LogTypes::DSPLLE] = new LogContainer("DSPLLE", "DSP LLE"); | ||
| 54 | m_Log[LogTypes::DSP_MAIL] = new LogContainer("DSPMails", "DSP Mails"); | ||
| 55 | m_Log[LogTypes::VIDEO] = new LogContainer("Video", "Video Backend"); | ||
| 56 | m_Log[LogTypes::AUDIO] = new LogContainer("Audio", "Audio Emulator"); | ||
| 57 | m_Log[LogTypes::DYNA_REC] = new LogContainer("JIT", "JIT"); | ||
| 58 | m_Log[LogTypes::CONSOLE] = new LogContainer("CONSOLE", "Dolphin Console"); | ||
| 59 | m_Log[LogTypes::OSREPORT] = new LogContainer("OSREPORT", "OSReport"); | ||
| 60 | m_Log[LogTypes::TIME] = new LogContainer("Time", "Core Timing"); | ||
| 61 | m_Log[LogTypes::LOADER] = new LogContainer("Loader", "Loader"); | ||
| 62 | m_Log[LogTypes::FILESYS] = new LogContainer("FileSys", "File System"); | ||
| 63 | m_Log[LogTypes::WII_IPC_HID] = new LogContainer("WII_IPC_HID", "WII IPC HID"); | ||
| 64 | m_Log[LogTypes::KERNEL] = new LogContainer("KERNEL", "KERNEL HLE"); | ||
| 65 | m_Log[LogTypes::WII_IPC_DVD] = new LogContainer("WII_IPC_DVD", "WII IPC DVD"); | ||
| 66 | m_Log[LogTypes::WII_IPC_ES] = new LogContainer("WII_IPC_ES", "WII IPC ES"); | ||
| 67 | m_Log[LogTypes::WII_IPC_FILEIO] = new LogContainer("WII_IPC_FILEIO", "WII IPC FILEIO"); | ||
| 68 | m_Log[LogTypes::RENDER] = new LogContainer("RENDER", "RENDER"); | ||
| 69 | m_Log[LogTypes::GPU] = new LogContainer("GPU", "GPU"); | ||
| 70 | m_Log[LogTypes::SVC] = new LogContainer("SVC", "Supervisor Call HLE"); | ||
| 71 | m_Log[LogTypes::NDMA] = new LogContainer("NDMA", "NDMA"); | ||
| 72 | m_Log[LogTypes::HLE] = new LogContainer("HLE", "High Level Emulation"); | ||
| 73 | m_Log[LogTypes::HW] = new LogContainer("HW", "Hardware"); | ||
| 74 | m_Log[LogTypes::ACTIONREPLAY] = new LogContainer("ActionReplay", "ActionReplay"); | ||
| 75 | m_Log[LogTypes::MEMCARD_MANAGER] = new LogContainer("MemCard Manager", "MemCard Manager"); | ||
| 76 | m_Log[LogTypes::NETPLAY] = new LogContainer("NETPLAY", "Netplay"); | ||
| 77 | m_Log[LogTypes::GUI] = new LogContainer("GUI", "GUI"); | ||
| 78 | |||
| 79 | m_fileLog = new FileLogListener(FileUtil::GetUserPath(F_MAINLOG_IDX).c_str()); | ||
| 80 | m_consoleLog = new ConsoleListener(); | ||
| 81 | m_debuggerLog = new DebuggerLogListener(); | ||
| 82 | |||
| 83 | for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | ||
| 84 | { | ||
| 85 | m_Log[i]->SetEnable(true); | ||
| 86 | m_Log[i]->AddListener(m_fileLog); | ||
| 87 | m_Log[i]->AddListener(m_consoleLog); | ||
| 88 | #ifdef _MSC_VER | ||
| 89 | if (IsDebuggerPresent()) | ||
| 90 | m_Log[i]->AddListener(m_debuggerLog); | ||
| 91 | #endif | ||
| 92 | } | ||
| 93 | |||
| 94 | m_consoleLog->Open(); | ||
| 95 | } | ||
| 96 | |||
| 97 | LogManager::~LogManager() | ||
| 98 | { | ||
| 99 | for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | ||
| 100 | { | ||
| 101 | m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_fileLog); | ||
| 102 | m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog); | ||
| 103 | m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_debuggerLog); | ||
| 104 | } | ||
| 105 | |||
| 106 | for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) | ||
| 107 | delete m_Log[i]; | ||
| 108 | |||
| 109 | delete m_fileLog; | ||
| 110 | delete m_consoleLog; | ||
| 111 | delete m_debuggerLog; | ||
| 112 | } | ||
| 113 | |||
| 114 | void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, | ||
| 115 | int line, const char* function, const char *fmt, va_list args) | ||
| 116 | { | ||
| 117 | char temp[MAX_MSGLEN]; | ||
| 118 | char msg[MAX_MSGLEN * 2]; | ||
| 119 | LogContainer *log = m_Log[type]; | ||
| 120 | |||
| 121 | if (!log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners()) | ||
| 122 | return; | ||
| 123 | |||
| 124 | Common::CharArrayFromFormatV(temp, MAX_MSGLEN, fmt, args); | ||
| 125 | |||
| 126 | static const char level_to_char[7] = "ONEWID"; | ||
| 127 | sprintf(msg, "%s %s:%u %c[%s] %s: %s\n", Common::Timer::GetTimeFormatted().c_str(), file, line, | ||
| 128 | level_to_char[(int)level], log->GetShortName(), function, temp); | ||
| 129 | |||
| 130 | #ifdef ANDROID | ||
| 131 | Host_SysMessage(msg); | ||
| 132 | #endif | ||
| 133 | log->Trigger(level, msg); | ||
| 134 | } | ||
| 135 | |||
| 136 | void LogManager::Init() | ||
| 137 | { | ||
| 138 | m_logManager = new LogManager(); | ||
| 139 | } | ||
| 140 | |||
| 141 | void LogManager::Shutdown() | ||
| 142 | { | ||
| 143 | delete m_logManager; | ||
| 144 | m_logManager = NULL; | ||
| 145 | } | ||
| 146 | |||
| 147 | LogContainer::LogContainer(const char* shortName, const char* fullName, bool enable) | ||
| 148 | : m_enable(enable) | ||
| 149 | { | ||
| 150 | strncpy(m_fullName, fullName, 128); | ||
| 151 | strncpy(m_shortName, shortName, 32); | ||
| 152 | m_level = LogTypes::MAX_LOGLEVEL; | ||
| 153 | } | ||
| 154 | |||
| 155 | // LogContainer | ||
| 156 | void LogContainer::AddListener(LogListener *listener) | ||
| 157 | { | ||
| 158 | std::lock_guard<std::mutex> lk(m_listeners_lock); | ||
| 159 | m_listeners.insert(listener); | ||
| 160 | } | ||
| 161 | |||
| 162 | void LogContainer::RemoveListener(LogListener *listener) | ||
| 163 | { | ||
| 164 | std::lock_guard<std::mutex> lk(m_listeners_lock); | ||
| 165 | m_listeners.erase(listener); | ||
| 166 | } | ||
| 167 | |||
| 168 | void LogContainer::Trigger(LogTypes::LOG_LEVELS level, const char *msg) | ||
| 169 | { | ||
| 170 | std::lock_guard<std::mutex> lk(m_listeners_lock); | ||
| 171 | |||
| 172 | std::set<LogListener*>::const_iterator i; | ||
| 173 | for (i = m_listeners.begin(); i != m_listeners.end(); ++i) | ||
| 174 | { | ||
| 175 | (*i)->Log(level, msg); | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | FileLogListener::FileLogListener(const char *filename) | ||
| 180 | { | ||
| 181 | OpenFStream(m_logfile, filename, std::ios::app); | ||
| 182 | SetEnable(true); | ||
| 183 | } | ||
| 184 | |||
| 185 | void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) | ||
| 186 | { | ||
| 187 | if (!IsEnabled() || !IsValid()) | ||
| 188 | return; | ||
| 189 | |||
| 190 | std::lock_guard<std::mutex> lk(m_log_lock); | ||
| 191 | m_logfile << msg << std::flush; | ||
| 192 | } | ||
| 193 | |||
| 194 | void DebuggerLogListener::Log(LogTypes::LOG_LEVELS, const char *msg) | ||
| 195 | { | ||
| 196 | #if _MSC_VER | ||
| 197 | ::OutputDebugStringA(msg); | ||
| 198 | #endif | ||
| 199 | } | ||
diff --git a/src/common/log_manager.h b/src/common/log_manager.h deleted file mode 100644 index baefc4ba8..000000000 --- a/src/common/log_manager.h +++ /dev/null | |||
| @@ -1,166 +0,0 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | ||
| 2 | // Licensed under GPLv2 | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/log.h" | ||
| 8 | #include "common/string_util.h" | ||
| 9 | #include "common/file_util.h" | ||
| 10 | |||
| 11 | #include <cstring> | ||
| 12 | #include <set> | ||
| 13 | #include <mutex> | ||
| 14 | |||
| 15 | #define MAX_MESSAGES 8000 | ||
| 16 | #define MAX_MSGLEN 1024 | ||
| 17 | |||
| 18 | |||
| 19 | // pure virtual interface | ||
| 20 | class LogListener | ||
| 21 | { | ||
| 22 | public: | ||
| 23 | virtual ~LogListener() {} | ||
| 24 | |||
| 25 | virtual void Log(LogTypes::LOG_LEVELS, const char *msg) = 0; | ||
| 26 | }; | ||
| 27 | |||
| 28 | class FileLogListener : public LogListener | ||
| 29 | { | ||
| 30 | public: | ||
| 31 | FileLogListener(const char *filename); | ||
| 32 | |||
| 33 | void Log(LogTypes::LOG_LEVELS, const char *msg) override; | ||
| 34 | |||
| 35 | bool IsValid() { return !m_logfile.fail(); } | ||
| 36 | bool IsEnabled() const { return m_enable; } | ||
| 37 | void SetEnable(bool enable) { m_enable = enable; } | ||
| 38 | |||
| 39 | const char* GetName() const { return "file"; } | ||
| 40 | |||
| 41 | private: | ||
| 42 | std::mutex m_log_lock; | ||
| 43 | std::ofstream m_logfile; | ||
| 44 | bool m_enable; | ||
| 45 | }; | ||
| 46 | |||
| 47 | class DebuggerLogListener : public LogListener | ||
| 48 | { | ||
| 49 | public: | ||
| 50 | void Log(LogTypes::LOG_LEVELS, const char *msg) override; | ||
| 51 | }; | ||
| 52 | |||
| 53 | class LogContainer | ||
| 54 | { | ||
| 55 | public: | ||
| 56 | LogContainer(const char* shortName, const char* fullName, bool enable = false); | ||
| 57 | |||
| 58 | const char* GetShortName() const { return m_shortName; } | ||
| 59 | const char* GetFullName() const { return m_fullName; } | ||
| 60 | |||
| 61 | void AddListener(LogListener* listener); | ||
| 62 | void RemoveListener(LogListener* listener); | ||
| 63 | |||
| 64 | void Trigger(LogTypes::LOG_LEVELS, const char *msg); | ||
| 65 | |||
| 66 | bool IsEnabled() const { return m_enable; } | ||
| 67 | void SetEnable(bool enable) { m_enable = enable; } | ||
| 68 | |||
| 69 | LogTypes::LOG_LEVELS GetLevel() const { return m_level; } | ||
| 70 | |||
| 71 | void SetLevel(LogTypes::LOG_LEVELS level) { m_level = level; } | ||
| 72 | |||
| 73 | bool HasListeners() const { return !m_listeners.empty(); } | ||
| 74 | |||
| 75 | private: | ||
| 76 | char m_fullName[128]; | ||
| 77 | char m_shortName[32]; | ||
| 78 | bool m_enable; | ||
| 79 | LogTypes::LOG_LEVELS m_level; | ||
| 80 | std::mutex m_listeners_lock; | ||
| 81 | std::set<LogListener*> m_listeners; | ||
| 82 | }; | ||
| 83 | |||
| 84 | class ConsoleListener; | ||
| 85 | |||
| 86 | class LogManager : NonCopyable | ||
| 87 | { | ||
| 88 | private: | ||
| 89 | LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS]; | ||
| 90 | FileLogListener *m_fileLog; | ||
| 91 | ConsoleListener *m_consoleLog; | ||
| 92 | DebuggerLogListener *m_debuggerLog; | ||
| 93 | static LogManager *m_logManager; // Singleton. Ugh. | ||
| 94 | |||
| 95 | LogManager(); | ||
| 96 | ~LogManager(); | ||
| 97 | public: | ||
| 98 | |||
| 99 | static u32 GetMaxLevel() { return LogTypes::MAX_LOGLEVEL; } | ||
| 100 | |||
| 101 | void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line, | ||
| 102 | const char* function, const char *fmt, va_list args); | ||
| 103 | |||
| 104 | void SetLogLevel(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level) | ||
| 105 | { | ||
| 106 | m_Log[type]->SetLevel(level); | ||
| 107 | } | ||
| 108 | |||
| 109 | void SetEnable(LogTypes::LOG_TYPE type, bool enable) | ||
| 110 | { | ||
| 111 | m_Log[type]->SetEnable(enable); | ||
| 112 | } | ||
| 113 | |||
| 114 | bool IsEnabled(LogTypes::LOG_TYPE type) const | ||
| 115 | { | ||
| 116 | return m_Log[type]->IsEnabled(); | ||
| 117 | } | ||
| 118 | |||
| 119 | const char* GetShortName(LogTypes::LOG_TYPE type) const | ||
| 120 | { | ||
| 121 | return m_Log[type]->GetShortName(); | ||
| 122 | } | ||
| 123 | |||
| 124 | const char* GetFullName(LogTypes::LOG_TYPE type) const | ||
| 125 | { | ||
| 126 | return m_Log[type]->GetFullName(); | ||
| 127 | } | ||
| 128 | |||
| 129 | void AddListener(LogTypes::LOG_TYPE type, LogListener *listener) | ||
| 130 | { | ||
| 131 | m_Log[type]->AddListener(listener); | ||
| 132 | } | ||
| 133 | |||
| 134 | void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener) | ||
| 135 | { | ||
| 136 | m_Log[type]->RemoveListener(listener); | ||
| 137 | } | ||
| 138 | |||
| 139 | FileLogListener *GetFileListener() const | ||
| 140 | { | ||
| 141 | return m_fileLog; | ||
| 142 | } | ||
| 143 | |||
| 144 | ConsoleListener *GetConsoleListener() const | ||
| 145 | { | ||
| 146 | return m_consoleLog; | ||
| 147 | } | ||
| 148 | |||
| 149 | DebuggerLogListener *GetDebuggerListener() const | ||
| 150 | { | ||
| 151 | return m_debuggerLog; | ||
| 152 | } | ||
| 153 | |||
| 154 | static LogManager* GetInstance() | ||
| 155 | { | ||
| 156 | return m_logManager; | ||
| 157 | } | ||
| 158 | |||
| 159 | static void SetInstance(LogManager *logManager) | ||
| 160 | { | ||
| 161 | m_logManager = logManager; | ||
| 162 | } | ||
| 163 | |||
| 164 | static void Init(); | ||
| 165 | static void Shutdown(); | ||
| 166 | }; | ||
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp new file mode 100644 index 000000000..816d1bb55 --- /dev/null +++ b/src/common/logging/backend.cpp | |||
| @@ -0,0 +1,151 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | |||
| 7 | #include "common/log.h" // For _dbg_assert_ | ||
| 8 | |||
| 9 | #include "common/logging/backend.h" | ||
| 10 | #include "common/logging/log.h" | ||
| 11 | #include "common/logging/text_formatter.h" | ||
| 12 | |||
| 13 | namespace Log { | ||
| 14 | |||
| 15 | static std::shared_ptr<Logger> global_logger; | ||
| 16 | |||
| 17 | /// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this. | ||
| 18 | #define ALL_LOG_CLASSES() \ | ||
| 19 | CLS(Log) \ | ||
| 20 | CLS(Common) \ | ||
| 21 | SUB(Common, Filesystem) \ | ||
| 22 | SUB(Common, Memory) \ | ||
| 23 | CLS(Core) \ | ||
| 24 | SUB(Core, ARM11) \ | ||
| 25 | CLS(Config) \ | ||
| 26 | CLS(Debug) \ | ||
| 27 | SUB(Debug, Emulated) \ | ||
| 28 | SUB(Debug, GPU) \ | ||
| 29 | SUB(Debug, Breakpoint) \ | ||
| 30 | CLS(Kernel) \ | ||
| 31 | SUB(Kernel, SVC) \ | ||
| 32 | CLS(Service) \ | ||
| 33 | SUB(Service, SRV) \ | ||
| 34 | SUB(Service, FS) \ | ||
| 35 | SUB(Service, APT) \ | ||
| 36 | SUB(Service, GSP) \ | ||
| 37 | SUB(Service, AC) \ | ||
| 38 | SUB(Service, PTM) \ | ||
| 39 | SUB(Service, CFG) \ | ||
| 40 | SUB(Service, DSP) \ | ||
| 41 | SUB(Service, HID) \ | ||
| 42 | CLS(HW) \ | ||
| 43 | SUB(HW, Memory) \ | ||
| 44 | SUB(HW, GPU) \ | ||
| 45 | CLS(Frontend) \ | ||
| 46 | CLS(Render) \ | ||
| 47 | SUB(Render, Software) \ | ||
| 48 | SUB(Render, OpenGL) \ | ||
| 49 | CLS(Loader) | ||
| 50 | |||
| 51 | Logger::Logger() { | ||
| 52 | // Register logging classes so that they can be queried at runtime | ||
| 53 | size_t parent_class; | ||
| 54 | all_classes.reserve((size_t)Class::Count); | ||
| 55 | |||
| 56 | #define CLS(x) \ | ||
| 57 | all_classes.push_back(Class::x); \ | ||
| 58 | parent_class = all_classes.size() - 1; | ||
| 59 | #define SUB(x, y) \ | ||
| 60 | all_classes.push_back(Class::x##_##y); \ | ||
| 61 | all_classes[parent_class].num_children += 1; | ||
| 62 | |||
| 63 | ALL_LOG_CLASSES() | ||
| 64 | #undef CLS | ||
| 65 | #undef SUB | ||
| 66 | |||
| 67 | // Ensures that ALL_LOG_CLASSES isn't missing any entries. | ||
| 68 | _dbg_assert_(Log, all_classes.size() == (size_t)Class::Count); | ||
| 69 | } | ||
| 70 | |||
| 71 | // GetClassName is a macro defined by Windows.h, grrr... | ||
| 72 | const char* Logger::GetLogClassName(Class log_class) { | ||
| 73 | switch (log_class) { | ||
| 74 | #define CLS(x) case Class::x: return #x; | ||
| 75 | #define SUB(x, y) case Class::x##_##y: return #x "." #y; | ||
| 76 | ALL_LOG_CLASSES() | ||
| 77 | #undef CLS | ||
| 78 | #undef SUB | ||
| 79 | } | ||
| 80 | return "Unknown"; | ||
| 81 | } | ||
| 82 | |||
| 83 | const char* Logger::GetLevelName(Level log_level) { | ||
| 84 | #define LVL(x) case Level::x: return #x | ||
| 85 | switch (log_level) { | ||
| 86 | LVL(Trace); | ||
| 87 | LVL(Debug); | ||
| 88 | LVL(Info); | ||
| 89 | LVL(Warning); | ||
| 90 | LVL(Error); | ||
| 91 | LVL(Critical); | ||
| 92 | } | ||
| 93 | return "Unknown"; | ||
| 94 | #undef LVL | ||
| 95 | } | ||
| 96 | |||
| 97 | void Logger::LogMessage(Entry entry) { | ||
| 98 | ring_buffer.Push(std::move(entry)); | ||
| 99 | } | ||
| 100 | |||
| 101 | size_t Logger::GetEntries(Entry* out_buffer, size_t buffer_len) { | ||
| 102 | return ring_buffer.BlockingPop(out_buffer, buffer_len); | ||
| 103 | } | ||
| 104 | |||
| 105 | std::shared_ptr<Logger> InitGlobalLogger() { | ||
| 106 | global_logger = std::make_shared<Logger>(); | ||
| 107 | return global_logger; | ||
| 108 | } | ||
| 109 | |||
| 110 | Entry CreateEntry(Class log_class, Level log_level, | ||
| 111 | const char* filename, unsigned int line_nr, const char* function, | ||
| 112 | const char* format, va_list args) { | ||
| 113 | using std::chrono::steady_clock; | ||
| 114 | using std::chrono::duration_cast; | ||
| 115 | |||
| 116 | static steady_clock::time_point time_origin = steady_clock::now(); | ||
| 117 | |||
| 118 | std::array<char, 4 * 1024> formatting_buffer; | ||
| 119 | |||
| 120 | Entry entry; | ||
| 121 | entry.timestamp = duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin); | ||
| 122 | entry.log_class = log_class; | ||
| 123 | entry.log_level = log_level; | ||
| 124 | |||
| 125 | snprintf(formatting_buffer.data(), formatting_buffer.size(), "%s:%s:%u", filename, function, line_nr); | ||
| 126 | entry.location = std::string(formatting_buffer.data()); | ||
| 127 | |||
| 128 | vsnprintf(formatting_buffer.data(), formatting_buffer.size(), format, args); | ||
| 129 | entry.message = std::string(formatting_buffer.data()); | ||
| 130 | |||
| 131 | return std::move(entry); | ||
| 132 | } | ||
| 133 | |||
| 134 | void LogMessage(Class log_class, Level log_level, | ||
| 135 | const char* filename, unsigned int line_nr, const char* function, | ||
| 136 | const char* format, ...) { | ||
| 137 | va_list args; | ||
| 138 | va_start(args, format); | ||
| 139 | Entry entry = CreateEntry(log_class, log_level, | ||
| 140 | filename, line_nr, function, format, args); | ||
| 141 | va_end(args); | ||
| 142 | |||
| 143 | if (global_logger != nullptr && !global_logger->IsClosed()) { | ||
| 144 | global_logger->LogMessage(std::move(entry)); | ||
| 145 | } else { | ||
| 146 | // Fall back to directly printing to stderr | ||
| 147 | PrintMessage(entry); | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | } | ||
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h new file mode 100644 index 000000000..1c44c929e --- /dev/null +++ b/src/common/logging/backend.h | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <cstdarg> | ||
| 8 | #include <memory> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | #include "common/concurrent_ring_buffer.h" | ||
| 12 | |||
| 13 | #include "common/logging/log.h" | ||
| 14 | |||
| 15 | namespace Log { | ||
| 16 | |||
| 17 | /** | ||
| 18 | * A log entry. Log entries are store in a structured format to permit more varied output | ||
| 19 | * formatting on different frontends, as well as facilitating filtering and aggregation. | ||
| 20 | */ | ||
| 21 | struct Entry { | ||
| 22 | std::chrono::microseconds timestamp; | ||
| 23 | Class log_class; | ||
| 24 | Level log_level; | ||
| 25 | std::string location; | ||
| 26 | std::string message; | ||
| 27 | |||
| 28 | Entry() = default; | ||
| 29 | |||
| 30 | // TODO(yuriks) Use defaulted move constructors once MSVC supports them | ||
| 31 | #define MOVE(member) member(std::move(o.member)) | ||
| 32 | Entry(Entry&& o) | ||
| 33 | : MOVE(timestamp), MOVE(log_class), MOVE(log_level), | ||
| 34 | MOVE(location), MOVE(message) | ||
| 35 | {} | ||
| 36 | #undef MOVE | ||
| 37 | |||
| 38 | Entry& operator=(const Entry&& o) { | ||
| 39 | #define MOVE(member) member = std::move(o.member) | ||
| 40 | MOVE(timestamp); | ||
| 41 | MOVE(log_class); | ||
| 42 | MOVE(log_level); | ||
| 43 | MOVE(location); | ||
| 44 | MOVE(message); | ||
| 45 | #undef MOVE | ||
| 46 | return *this; | ||
| 47 | } | ||
| 48 | }; | ||
| 49 | |||
| 50 | struct ClassInfo { | ||
| 51 | Class log_class; | ||
| 52 | |||
| 53 | /** | ||
| 54 | * Total number of (direct or indirect) sub classes this class has. If any, they follow in | ||
| 55 | * sequence after this class in the class list. | ||
| 56 | */ | ||
| 57 | unsigned int num_children = 0; | ||
| 58 | |||
| 59 | ClassInfo(Class log_class) : log_class(log_class) {} | ||
| 60 | }; | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Logging management class. This class has the dual purpose of acting as an exchange point between | ||
| 64 | * the logging clients and the log outputter, as well as containing reflection info about available | ||
| 65 | * log classes. | ||
| 66 | */ | ||
| 67 | class Logger { | ||
| 68 | private: | ||
| 69 | using Buffer = Common::ConcurrentRingBuffer<Entry, 16 * 1024 / sizeof(Entry)>; | ||
| 70 | |||
| 71 | public: | ||
| 72 | static const size_t QUEUE_CLOSED = Buffer::QUEUE_CLOSED; | ||
| 73 | |||
| 74 | Logger(); | ||
| 75 | |||
| 76 | /** | ||
| 77 | * Returns a list of all vector classes and subclasses. The sequence returned is a pre-order of | ||
| 78 | * classes and subclasses, which together with the `num_children` field in ClassInfo, allows | ||
| 79 | * you to recover the hierarchy. | ||
| 80 | */ | ||
| 81 | const std::vector<ClassInfo>& GetClasses() const { return all_classes; } | ||
| 82 | |||
| 83 | /** | ||
| 84 | * Returns the name of the passed log class as a C-string. Subclasses are separated by periods | ||
| 85 | * instead of underscores as in the enumeration. | ||
| 86 | */ | ||
| 87 | static const char* GetLogClassName(Class log_class); | ||
| 88 | |||
| 89 | /** | ||
| 90 | * Returns the name of the passed log level as a C-string. | ||
| 91 | */ | ||
| 92 | static const char* GetLevelName(Level log_level); | ||
| 93 | |||
| 94 | /** | ||
| 95 | * Appends a messages to the log buffer. | ||
| 96 | * @note This function is thread safe. | ||
| 97 | */ | ||
| 98 | void LogMessage(Entry entry); | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Retrieves a batch of messages from the log buffer, blocking until they are available. | ||
| 102 | * @note This function is thread safe. | ||
| 103 | * | ||
| 104 | * @param out_buffer Destination buffer that will receive the log entries. | ||
| 105 | * @param buffer_len The maximum size of `out_buffer`. | ||
| 106 | * @return The number of entries stored. In case the logger is shutting down, `QUEUE_CLOSED` is | ||
| 107 | * returned, no entries are stored and the logger should shutdown. | ||
| 108 | */ | ||
| 109 | size_t GetEntries(Entry* out_buffer, size_t buffer_len); | ||
| 110 | |||
| 111 | /** | ||
| 112 | * Initiates a shutdown of the logger. This will indicate to log output clients that they | ||
| 113 | * should shutdown. | ||
| 114 | */ | ||
| 115 | void Close() { ring_buffer.Close(); } | ||
| 116 | |||
| 117 | /** | ||
| 118 | * Returns true if Close() has already been called on the Logger. | ||
| 119 | */ | ||
| 120 | bool IsClosed() const { return ring_buffer.IsClosed(); } | ||
| 121 | |||
| 122 | private: | ||
| 123 | Buffer ring_buffer; | ||
| 124 | std::vector<ClassInfo> all_classes; | ||
| 125 | }; | ||
| 126 | |||
| 127 | /// Creates a log entry by formatting the given source location, and message. | ||
| 128 | Entry CreateEntry(Class log_class, Level log_level, | ||
| 129 | const char* filename, unsigned int line_nr, const char* function, | ||
| 130 | const char* format, va_list args); | ||
| 131 | /// Initializes the default Logger. | ||
| 132 | std::shared_ptr<Logger> InitGlobalLogger(); | ||
| 133 | |||
| 134 | } | ||
diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp new file mode 100644 index 000000000..50f2e13f4 --- /dev/null +++ b/src/common/logging/filter.cpp | |||
| @@ -0,0 +1,132 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | |||
| 7 | #include "common/logging/filter.h" | ||
| 8 | #include "common/logging/backend.h" | ||
| 9 | #include "common/string_util.h" | ||
| 10 | |||
| 11 | namespace Log { | ||
| 12 | |||
| 13 | Filter::Filter(Level default_level) { | ||
| 14 | ResetAll(default_level); | ||
| 15 | } | ||
| 16 | |||
| 17 | void Filter::ResetAll(Level level) { | ||
| 18 | class_levels.fill(level); | ||
| 19 | } | ||
| 20 | |||
| 21 | void Filter::SetClassLevel(Class log_class, Level level) { | ||
| 22 | class_levels[static_cast<size_t>(log_class)] = level; | ||
| 23 | } | ||
| 24 | |||
| 25 | void Filter::SetSubclassesLevel(const ClassInfo& log_class, Level level) { | ||
| 26 | const size_t log_class_i = static_cast<size_t>(log_class.log_class); | ||
| 27 | |||
| 28 | const size_t begin = log_class_i + 1; | ||
| 29 | const size_t end = begin + log_class.num_children; | ||
| 30 | for (size_t i = begin; begin < end; ++i) { | ||
| 31 | class_levels[i] = level; | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | void Filter::ParseFilterString(const std::string& filter_str) { | ||
| 36 | auto clause_begin = filter_str.cbegin(); | ||
| 37 | while (clause_begin != filter_str.cend()) { | ||
| 38 | auto clause_end = std::find(clause_begin, filter_str.cend(), ' '); | ||
| 39 | |||
| 40 | // If clause isn't empty | ||
| 41 | if (clause_end != clause_begin) { | ||
| 42 | ParseFilterRule(clause_begin, clause_end); | ||
| 43 | } | ||
| 44 | |||
| 45 | if (clause_end != filter_str.cend()) { | ||
| 46 | // Skip over the whitespace | ||
| 47 | ++clause_end; | ||
| 48 | } | ||
| 49 | clause_begin = clause_end; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | template <typename It> | ||
| 54 | static Level GetLevelByName(const It begin, const It end) { | ||
| 55 | for (u8 i = 0; i < static_cast<u8>(Level::Count); ++i) { | ||
| 56 | const char* level_name = Logger::GetLevelName(static_cast<Level>(i)); | ||
| 57 | if (Common::ComparePartialString(begin, end, level_name)) { | ||
| 58 | return static_cast<Level>(i); | ||
| 59 | } | ||
| 60 | } | ||
| 61 | return Level::Count; | ||
| 62 | } | ||
| 63 | |||
| 64 | template <typename It> | ||
| 65 | static Class GetClassByName(const It begin, const It end) { | ||
| 66 | for (ClassType i = 0; i < static_cast<ClassType>(Class::Count); ++i) { | ||
| 67 | const char* level_name = Logger::GetLogClassName(static_cast<Class>(i)); | ||
| 68 | if (Common::ComparePartialString(begin, end, level_name)) { | ||
| 69 | return static_cast<Class>(i); | ||
| 70 | } | ||
| 71 | } | ||
| 72 | return Class::Count; | ||
| 73 | } | ||
| 74 | |||
| 75 | template <typename InputIt, typename T> | ||
| 76 | static InputIt find_last(InputIt begin, const InputIt end, const T& value) { | ||
| 77 | auto match = end; | ||
| 78 | while (begin != end) { | ||
| 79 | auto new_match = std::find(begin, end, value); | ||
| 80 | if (new_match != end) { | ||
| 81 | match = new_match; | ||
| 82 | ++new_match; | ||
| 83 | } | ||
| 84 | begin = new_match; | ||
| 85 | } | ||
| 86 | return match; | ||
| 87 | } | ||
| 88 | |||
| 89 | bool Filter::ParseFilterRule(const std::string::const_iterator begin, | ||
| 90 | const std::string::const_iterator end) { | ||
| 91 | auto level_separator = std::find(begin, end, ':'); | ||
| 92 | if (level_separator == end) { | ||
| 93 | LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: %s", | ||
| 94 | std::string(begin, end).c_str()); | ||
| 95 | return false; | ||
| 96 | } | ||
| 97 | |||
| 98 | const Level level = GetLevelByName(level_separator + 1, end); | ||
| 99 | if (level == Level::Count) { | ||
| 100 | LOG_ERROR(Log, "Unknown log level in filter: %s", std::string(begin, end).c_str()); | ||
| 101 | return false; | ||
| 102 | } | ||
| 103 | |||
| 104 | if (Common::ComparePartialString(begin, level_separator, "*")) { | ||
| 105 | ResetAll(level); | ||
| 106 | return true; | ||
| 107 | } | ||
| 108 | |||
| 109 | auto class_name_end = find_last(begin, level_separator, '.'); | ||
| 110 | if (class_name_end != level_separator && | ||
| 111 | !Common::ComparePartialString(class_name_end + 1, level_separator, "*")) { | ||
| 112 | class_name_end = level_separator; | ||
| 113 | } | ||
| 114 | |||
| 115 | const Class log_class = GetClassByName(begin, class_name_end); | ||
| 116 | if (log_class == Class::Count) { | ||
| 117 | LOG_ERROR(Log, "Unknown log class in filter: %s", std::string(begin, end).c_str()); | ||
| 118 | return false; | ||
| 119 | } | ||
| 120 | |||
| 121 | if (class_name_end == level_separator) { | ||
| 122 | SetClassLevel(log_class, level); | ||
| 123 | } | ||
| 124 | SetSubclassesLevel(log_class, level); | ||
| 125 | return true; | ||
| 126 | } | ||
| 127 | |||
| 128 | bool Filter::CheckMessage(Class log_class, Level level) const { | ||
| 129 | return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]); | ||
| 130 | } | ||
| 131 | |||
| 132 | } | ||
diff --git a/src/common/logging/filter.h b/src/common/logging/filter.h new file mode 100644 index 000000000..c3da9989f --- /dev/null +++ b/src/common/logging/filter.h | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <array> | ||
| 6 | #include <string> | ||
| 7 | |||
| 8 | #include "common/logging/log.h" | ||
| 9 | |||
| 10 | namespace Log { | ||
| 11 | |||
| 12 | struct ClassInfo; | ||
| 13 | |||
| 14 | /** | ||
| 15 | * Implements a log message filter which allows different log classes to have different minimum | ||
| 16 | * severity levels. The filter can be changed at runtime and can be parsed from a string to allow | ||
| 17 | * editing via the interface or loading from a configuration file. | ||
| 18 | */ | ||
| 19 | class Filter { | ||
| 20 | public: | ||
| 21 | /// Initializes the filter with all classes having `default_level` as the minimum level. | ||
| 22 | Filter(Level default_level); | ||
| 23 | |||
| 24 | /// Resets the filter so that all classes have `level` as the minimum displayed level. | ||
| 25 | void ResetAll(Level level); | ||
| 26 | /// Sets the minimum level of `log_class` (and not of its subclasses) to `level`. | ||
| 27 | void SetClassLevel(Class log_class, Level level); | ||
| 28 | /** | ||
| 29 | * Sets the minimum level of all of `log_class` subclasses to `level`. The level of `log_class` | ||
| 30 | * itself is not changed. | ||
| 31 | */ | ||
| 32 | void SetSubclassesLevel(const ClassInfo& log_class, Level level); | ||
| 33 | |||
| 34 | /** | ||
| 35 | * Parses a filter string and applies it to this filter. | ||
| 36 | * | ||
| 37 | * A filter string consists of a space-separated list of filter rules, each of the format | ||
| 38 | * `<class>:<level>`. `<class>` is a log class name, with subclasses separated using periods. | ||
| 39 | * A rule for a given class also affects all of its subclasses. `*` wildcards are allowed and | ||
| 40 | * can be used to apply a rule to all classes or to all subclasses of a class without affecting | ||
| 41 | * the parent class. `<level>` a severity level name which will be set as the minimum logging | ||
| 42 | * level of the matched classes. Rules are applied left to right, with each rule overriding | ||
| 43 | * previous ones in the sequence. | ||
| 44 | * | ||
| 45 | * A few examples of filter rules: | ||
| 46 | * - `*:Info` -- Resets the level of all classes to Info. | ||
| 47 | * - `Service:Info` -- Sets the level of Service and all subclasses (Service.FS, Service.APT, | ||
| 48 | * etc.) to Info. | ||
| 49 | * - `Service.*:Debug` -- Sets the level of all Service subclasses to Debug, while leaving the | ||
| 50 | * level of Service unchanged. | ||
| 51 | * - `Service.FS:Trace` -- Sets the level of the Service.FS class to Trace. | ||
| 52 | */ | ||
| 53 | void ParseFilterString(const std::string& filter_str); | ||
| 54 | bool ParseFilterRule(const std::string::const_iterator start, const std::string::const_iterator end); | ||
| 55 | |||
| 56 | /// Matches class/level combination against the filter, returning true if it passed. | ||
| 57 | bool CheckMessage(Class log_class, Level level) const; | ||
| 58 | |||
| 59 | private: | ||
| 60 | std::array<Level, (size_t)Class::Count> class_levels; | ||
| 61 | }; | ||
| 62 | |||
| 63 | } | ||
diff --git a/src/common/logging/log.h b/src/common/logging/log.h new file mode 100644 index 000000000..d1c391862 --- /dev/null +++ b/src/common/logging/log.h | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <cassert> | ||
| 8 | #include <chrono> | ||
| 9 | #include <string> | ||
| 10 | |||
| 11 | #include "common/common_types.h" | ||
| 12 | |||
| 13 | namespace Log { | ||
| 14 | |||
| 15 | /// Specifies the severity or level of detail of the log message. | ||
| 16 | enum class Level : u8 { | ||
| 17 | Trace, ///< Extremely detailed and repetitive debugging information that is likely to | ||
| 18 | /// pollute logs. | ||
| 19 | Debug, ///< Less detailed debugging information. | ||
| 20 | Info, ///< Status information from important points during execution. | ||
| 21 | Warning, ///< Minor or potential problems found during execution of a task. | ||
| 22 | Error, ///< Major problems found during execution of a task that prevent it from being | ||
| 23 | /// completed. | ||
| 24 | Critical, ///< Major problems during execution that threathen the stability of the entire | ||
| 25 | /// application. | ||
| 26 | |||
| 27 | Count ///< Total number of logging levels | ||
| 28 | }; | ||
| 29 | |||
| 30 | typedef u8 ClassType; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * Specifies the sub-system that generated the log message. | ||
| 34 | * | ||
| 35 | * @note If you add a new entry here, also add a corresponding one to `ALL_LOG_CLASSES` in log.cpp. | ||
| 36 | */ | ||
| 37 | enum class Class : ClassType { | ||
| 38 | Log, ///< Messages about the log system itself | ||
| 39 | Common, ///< Library routines | ||
| 40 | Common_Filesystem, ///< Filesystem interface library | ||
| 41 | Common_Memory, ///< Memory mapping and management functions | ||
| 42 | Core, ///< LLE emulation core | ||
| 43 | Core_ARM11, ///< ARM11 CPU core | ||
| 44 | Config, ///< Emulator configuration (including commandline) | ||
| 45 | Debug, ///< Debugging tools | ||
| 46 | Debug_Emulated, ///< Debug messages from the emulated programs | ||
| 47 | Debug_GPU, ///< GPU debugging tools | ||
| 48 | Debug_Breakpoint, ///< Logging breakpoints and watchpoints | ||
| 49 | Kernel, ///< The HLE implementation of the CTR kernel | ||
| 50 | Kernel_SVC, ///< Kernel system calls | ||
| 51 | Service, ///< HLE implementation of system services. Each major service | ||
| 52 | /// should have its own subclass. | ||
| 53 | Service_SRV, ///< The SRV (Service Directory) implementation | ||
| 54 | Service_FS, ///< The FS (Filesystem) service implementation | ||
| 55 | Service_APT, ///< The APT (Applets) service | ||
| 56 | Service_GSP, ///< The GSP (GPU control) service | ||
| 57 | Service_AC, ///< The AC (WiFi status) service | ||
| 58 | Service_PTM, ///< The PTM (Power status & misc.) service | ||
| 59 | Service_CFG, ///< The CFG (Configuration) service | ||
| 60 | Service_DSP, ///< The DSP (DSP control) service | ||
| 61 | Service_HID, ///< The HID (User input) service | ||
| 62 | HW, ///< Low-level hardware emulation | ||
| 63 | HW_Memory, ///< Memory-map and address translation | ||
| 64 | HW_GPU, ///< GPU control emulation | ||
| 65 | Frontend, ///< Emulator UI | ||
| 66 | Render, ///< Emulator video output and hardware acceleration | ||
| 67 | Render_Software, ///< Software renderer backend | ||
| 68 | Render_OpenGL, ///< OpenGL backend | ||
| 69 | Loader, ///< ROM loader | ||
| 70 | |||
| 71 | Count ///< Total number of logging classes | ||
| 72 | }; | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Level below which messages are simply discarded without buffering regardless of the display | ||
| 76 | * settings. | ||
| 77 | */ | ||
| 78 | const Level MINIMUM_LEVEL = | ||
| 79 | #ifdef _DEBUG | ||
| 80 | Level::Trace; | ||
| 81 | #else | ||
| 82 | Level::Debug; | ||
| 83 | #endif | ||
| 84 | |||
| 85 | /** | ||
| 86 | * Logs a message to the global logger. This proxy exists to avoid exposing the details of the | ||
| 87 | * Logger class, including the ConcurrentRingBuffer template, to all files that desire to log | ||
| 88 | * messages, reducing unecessary recompilations. | ||
| 89 | */ | ||
| 90 | void LogMessage(Class log_class, Level log_level, | ||
| 91 | const char* filename, unsigned int line_nr, const char* function, | ||
| 92 | #ifdef _MSC_VER | ||
| 93 | _Printf_format_string_ | ||
| 94 | #endif | ||
| 95 | const char* format, ...) | ||
| 96 | #ifdef __GNUC__ | ||
| 97 | __attribute__((format(printf, 6, 7))) | ||
| 98 | #endif | ||
| 99 | ; | ||
| 100 | |||
| 101 | } // namespace Log | ||
| 102 | |||
| 103 | #define LOG_GENERIC(log_class, log_level, ...) \ | ||
| 104 | do { \ | ||
| 105 | if (::Log::Level::log_level >= ::Log::MINIMUM_LEVEL) \ | ||
| 106 | ::Log::LogMessage(::Log::Class::log_class, ::Log::Level::log_level, \ | ||
| 107 | __FILE__, __LINE__, __func__, __VA_ARGS__); \ | ||
| 108 | } while (0) | ||
| 109 | |||
| 110 | #define LOG_TRACE( log_class, ...) LOG_GENERIC(log_class, Trace, __VA_ARGS__) | ||
| 111 | #define LOG_DEBUG( log_class, ...) LOG_GENERIC(log_class, Debug, __VA_ARGS__) | ||
| 112 | #define LOG_INFO( log_class, ...) LOG_GENERIC(log_class, Info, __VA_ARGS__) | ||
| 113 | #define LOG_WARNING( log_class, ...) LOG_GENERIC(log_class, Warning, __VA_ARGS__) | ||
| 114 | #define LOG_ERROR( log_class, ...) LOG_GENERIC(log_class, Error, __VA_ARGS__) | ||
| 115 | #define LOG_CRITICAL(log_class, ...) LOG_GENERIC(log_class, Critical, __VA_ARGS__) | ||
diff --git a/src/common/logging/text_formatter.cpp b/src/common/logging/text_formatter.cpp new file mode 100644 index 000000000..ef5739d84 --- /dev/null +++ b/src/common/logging/text_formatter.cpp | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <array> | ||
| 6 | #include <cstdio> | ||
| 7 | |||
| 8 | #ifdef _WIN32 | ||
| 9 | # define WIN32_LEAN_AND_MEAN | ||
| 10 | # include <Windows.h> | ||
| 11 | #endif | ||
| 12 | |||
| 13 | #include "common/logging/backend.h" | ||
| 14 | #include "common/logging/filter.h" | ||
| 15 | #include "common/logging/log.h" | ||
| 16 | #include "common/logging/text_formatter.h" | ||
| 17 | |||
| 18 | #include "common/string_util.h" | ||
| 19 | |||
| 20 | namespace Log { | ||
| 21 | |||
| 22 | // TODO(bunnei): This should be moved to a generic path manipulation library | ||
| 23 | const char* TrimSourcePath(const char* path, const char* root) { | ||
| 24 | const char* p = path; | ||
| 25 | |||
| 26 | while (*p != '\0') { | ||
| 27 | const char* next_slash = p; | ||
| 28 | while (*next_slash != '\0' && *next_slash != '/' && *next_slash != '\\') { | ||
| 29 | ++next_slash; | ||
| 30 | } | ||
| 31 | |||
| 32 | bool is_src = Common::ComparePartialString(p, next_slash, root); | ||
| 33 | p = next_slash; | ||
| 34 | |||
| 35 | if (*p != '\0') { | ||
| 36 | ++p; | ||
| 37 | } | ||
| 38 | if (is_src) { | ||
| 39 | path = p; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | return path; | ||
| 43 | } | ||
| 44 | |||
| 45 | void FormatLogMessage(const Entry& entry, char* out_text, size_t text_len) { | ||
| 46 | unsigned int time_seconds = static_cast<unsigned int>(entry.timestamp.count() / 1000000); | ||
| 47 | unsigned int time_fractional = static_cast<unsigned int>(entry.timestamp.count() % 1000000); | ||
| 48 | |||
| 49 | const char* class_name = Logger::GetLogClassName(entry.log_class); | ||
| 50 | const char* level_name = Logger::GetLevelName(entry.log_level); | ||
| 51 | |||
| 52 | snprintf(out_text, text_len, "[%4u.%06u] %s <%s> %s: %s", | ||
| 53 | time_seconds, time_fractional, class_name, level_name, | ||
| 54 | TrimSourcePath(entry.location.c_str()), entry.message.c_str()); | ||
| 55 | } | ||
| 56 | |||
| 57 | void PrintMessage(const Entry& entry) { | ||
| 58 | std::array<char, 4 * 1024> format_buffer; | ||
| 59 | FormatLogMessage(entry, format_buffer.data(), format_buffer.size()); | ||
| 60 | fputs(format_buffer.data(), stderr); | ||
| 61 | fputc('\n', stderr); | ||
| 62 | } | ||
| 63 | |||
| 64 | void PrintColoredMessage(const Entry& entry) { | ||
| 65 | #ifdef _WIN32 | ||
| 66 | static HANDLE console_handle = GetStdHandle(STD_ERROR_HANDLE); | ||
| 67 | |||
| 68 | CONSOLE_SCREEN_BUFFER_INFO original_info = {0}; | ||
| 69 | GetConsoleScreenBufferInfo(console_handle, &original_info); | ||
| 70 | |||
| 71 | WORD color = 0; | ||
| 72 | switch (entry.log_level) { | ||
| 73 | case Level::Trace: // Grey | ||
| 74 | color = FOREGROUND_INTENSITY; break; | ||
| 75 | case Level::Debug: // Cyan | ||
| 76 | color = FOREGROUND_GREEN | FOREGROUND_BLUE; break; | ||
| 77 | case Level::Info: // Bright gray | ||
| 78 | color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; break; | ||
| 79 | case Level::Warning: // Bright yellow | ||
| 80 | color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; break; | ||
| 81 | case Level::Error: // Bright red | ||
| 82 | color = FOREGROUND_RED | FOREGROUND_INTENSITY; break; | ||
| 83 | case Level::Critical: // Bright magenta | ||
| 84 | color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; break; | ||
| 85 | } | ||
| 86 | |||
| 87 | SetConsoleTextAttribute(console_handle, color); | ||
| 88 | #else | ||
| 89 | # define ESC "\x1b" | ||
| 90 | const char* color = ""; | ||
| 91 | switch (entry.log_level) { | ||
| 92 | case Level::Trace: // Grey | ||
| 93 | color = ESC "[1;30m"; break; | ||
| 94 | case Level::Debug: // Cyan | ||
| 95 | color = ESC "[0;36m"; break; | ||
| 96 | case Level::Info: // Bright gray | ||
| 97 | color = ESC "[0;37m"; break; | ||
| 98 | case Level::Warning: // Bright yellow | ||
| 99 | color = ESC "[1;33m"; break; | ||
| 100 | case Level::Error: // Bright red | ||
| 101 | color = ESC "[1;31m"; break; | ||
| 102 | case Level::Critical: // Bright magenta | ||
| 103 | color = ESC "[1;35m"; break; | ||
| 104 | } | ||
| 105 | |||
| 106 | fputs(color, stderr); | ||
| 107 | #endif | ||
| 108 | |||
| 109 | PrintMessage(entry); | ||
| 110 | |||
| 111 | #ifdef _WIN32 | ||
| 112 | SetConsoleTextAttribute(console_handle, original_info.wAttributes); | ||
| 113 | #else | ||
| 114 | fputs(ESC "[0m", stderr); | ||
| 115 | # undef ESC | ||
| 116 | #endif | ||
| 117 | } | ||
| 118 | |||
| 119 | void TextLoggingLoop(std::shared_ptr<Logger> logger, const Filter* filter) { | ||
| 120 | std::array<Entry, 256> entry_buffer; | ||
| 121 | |||
| 122 | while (true) { | ||
| 123 | size_t num_entries = logger->GetEntries(entry_buffer.data(), entry_buffer.size()); | ||
| 124 | if (num_entries == Logger::QUEUE_CLOSED) { | ||
| 125 | break; | ||
| 126 | } | ||
| 127 | for (size_t i = 0; i < num_entries; ++i) { | ||
| 128 | const Entry& entry = entry_buffer[i]; | ||
| 129 | if (filter->CheckMessage(entry.log_class, entry.log_level)) { | ||
| 130 | PrintColoredMessage(entry); | ||
| 131 | } | ||
| 132 | } | ||
| 133 | } | ||
| 134 | } | ||
| 135 | |||
| 136 | } | ||
diff --git a/src/common/logging/text_formatter.h b/src/common/logging/text_formatter.h new file mode 100644 index 000000000..2f05794f0 --- /dev/null +++ b/src/common/logging/text_formatter.h | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <cstddef> | ||
| 8 | #include <memory> | ||
| 9 | |||
| 10 | namespace Log { | ||
| 11 | |||
| 12 | class Logger; | ||
| 13 | struct Entry; | ||
| 14 | class Filter; | ||
| 15 | |||
| 16 | /** | ||
| 17 | * Attempts to trim an arbitrary prefix from `path`, leaving only the part starting at `root`. It's | ||
| 18 | * intended to be used to strip a system-specific build directory from the `__FILE__` macro, | ||
| 19 | * leaving only the path relative to the sources root. | ||
| 20 | * | ||
| 21 | * @param path The input file path as a null-terminated string | ||
| 22 | * @param root The name of the root source directory as a null-terminated string. Path up to and | ||
| 23 | * including the last occurence of this name will be stripped | ||
| 24 | * @return A pointer to the same string passed as `path`, but starting at the trimmed portion | ||
| 25 | */ | ||
| 26 | const char* TrimSourcePath(const char* path, const char* root = "src"); | ||
| 27 | |||
| 28 | /// Formats a log entry into the provided text buffer. | ||
| 29 | void FormatLogMessage(const Entry& entry, char* out_text, size_t text_len); | ||
| 30 | /// Formats and prints a log entry to stderr. | ||
| 31 | void PrintMessage(const Entry& entry); | ||
| 32 | /// Prints the same message as `PrintMessage`, but colored acoording to the severity level. | ||
| 33 | void PrintColoredMessage(const Entry& entry); | ||
| 34 | |||
| 35 | /** | ||
| 36 | * Logging loop that repeatedly reads messages from the provided logger and prints them to the | ||
| 37 | * console. It is the baseline barebones log outputter. | ||
| 38 | */ | ||
| 39 | void TextLoggingLoop(std::shared_ptr<Logger> logger, const Filter* filter); | ||
| 40 | |||
| 41 | } | ||
diff --git a/src/common/make_unique.h b/src/common/make_unique.h new file mode 100644 index 000000000..2a7b76412 --- /dev/null +++ b/src/common/make_unique.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | |||
| 9 | namespace Common { | ||
| 10 | |||
| 11 | template <typename T, typename... Args> | ||
| 12 | std::unique_ptr<T> make_unique(Args&&... args) { | ||
| 13 | return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); | ||
| 14 | } | ||
| 15 | |||
| 16 | } // namespace | ||
diff --git a/src/common/math_util.cpp b/src/common/math_util.cpp index 3613e82a6..a83592dd2 100644 --- a/src/common/math_util.cpp +++ b/src/common/math_util.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | 5 | ||
diff --git a/src/common/math_util.h b/src/common/math_util.h index b10a25c13..43b0e0dc3 100644 --- a/src/common/math_util.h +++ b/src/common/math_util.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/mem_arena.cpp b/src/common/mem_arena.cpp index 67dbaf509..9904d2472 100644 --- a/src/common/mem_arena.cpp +++ b/src/common/mem_arena.cpp | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | #ifdef IOS | 32 | #ifdef IOS |
| 33 | void* globalbase = NULL; | 33 | void* globalbase = nullptr; |
| 34 | #endif | 34 | #endif |
| 35 | 35 | ||
| 36 | #ifdef ANDROID | 36 | #ifdef ANDROID |
| @@ -71,7 +71,7 @@ int ashmem_create_region(const char *name, size_t size) | |||
| 71 | return fd; | 71 | return fd; |
| 72 | 72 | ||
| 73 | error: | 73 | error: |
| 74 | ERROR_LOG(MEMMAP, "NASTY ASHMEM ERROR: ret = %08x", ret); | 74 | LOG_ERROR(Common_Memory, "NASTY ASHMEM ERROR: ret = %08x", ret); |
| 75 | close(fd); | 75 | close(fd); |
| 76 | return ret; | 76 | return ret; |
| 77 | } | 77 | } |
| @@ -121,7 +121,7 @@ void MemArena::GrabLowMemSpace(size_t size) | |||
| 121 | { | 121 | { |
| 122 | #ifdef _WIN32 | 122 | #ifdef _WIN32 |
| 123 | #ifndef _XBOX | 123 | #ifndef _XBOX |
| 124 | hMemoryMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)(size), NULL); | 124 | hMemoryMapping = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, (DWORD)(size), nullptr); |
| 125 | GetSystemInfo(&sysInfo); | 125 | GetSystemInfo(&sysInfo); |
| 126 | #endif | 126 | #endif |
| 127 | #elif defined(ANDROID) | 127 | #elif defined(ANDROID) |
| @@ -130,7 +130,7 @@ void MemArena::GrabLowMemSpace(size_t size) | |||
| 130 | // Note that it appears that ashmem is pinned by default, so no need to pin. | 130 | // Note that it appears that ashmem is pinned by default, so no need to pin. |
| 131 | if (fd < 0) | 131 | if (fd < 0) |
| 132 | { | 132 | { |
| 133 | ERROR_LOG(MEMMAP, "Failed to grab ashmem space of size: %08x errno: %d", (int)size, (int)(errno)); | 133 | LOG_ERROR(Common_Memory, "Failed to grab ashmem space of size: %08x errno: %d", (int)size, (int)(errno)); |
| 134 | return; | 134 | return; |
| 135 | } | 135 | } |
| 136 | #else | 136 | #else |
| @@ -148,12 +148,12 @@ void MemArena::GrabLowMemSpace(size_t size) | |||
| 148 | } | 148 | } |
| 149 | else if (errno != EEXIST) | 149 | else if (errno != EEXIST) |
| 150 | { | 150 | { |
| 151 | ERROR_LOG(MEMMAP, "shm_open failed: %s", strerror(errno)); | 151 | LOG_ERROR(Common_Memory, "shm_open failed: %s", strerror(errno)); |
| 152 | return; | 152 | return; |
| 153 | } | 153 | } |
| 154 | } | 154 | } |
| 155 | if (ftruncate(fd, size) < 0) | 155 | if (ftruncate(fd, size) < 0) |
| 156 | ERROR_LOG(MEMMAP, "Failed to allocate low memory space"); | 156 | LOG_ERROR(Common_Memory, "Failed to allocate low memory space"); |
| 157 | #endif | 157 | #endif |
| 158 | } | 158 | } |
| 159 | 159 | ||
| @@ -178,7 +178,7 @@ void *MemArena::CreateView(s64 offset, size_t size, void *base) | |||
| 178 | #ifdef _XBOX | 178 | #ifdef _XBOX |
| 179 | size = roundup(size); | 179 | size = roundup(size); |
| 180 | // use 64kb pages | 180 | // use 64kb pages |
| 181 | void * ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); | 181 | void * ptr = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); |
| 182 | return ptr; | 182 | return ptr; |
| 183 | #else | 183 | #else |
| 184 | size = roundup(size); | 184 | size = roundup(size); |
| @@ -197,7 +197,7 @@ void *MemArena::CreateView(s64 offset, size_t size, void *base) | |||
| 197 | 197 | ||
| 198 | if (retval == MAP_FAILED) | 198 | if (retval == MAP_FAILED) |
| 199 | { | 199 | { |
| 200 | NOTICE_LOG(MEMMAP, "mmap failed"); | 200 | LOG_ERROR(Common_Memory, "mmap failed"); |
| 201 | return nullptr; | 201 | return nullptr; |
| 202 | } | 202 | } |
| 203 | return retval; | 203 | return retval; |
| @@ -243,8 +243,8 @@ u8* MemArena::Find4GBBase() | |||
| 243 | return base; | 243 | return base; |
| 244 | #else | 244 | #else |
| 245 | #ifdef IOS | 245 | #ifdef IOS |
| 246 | void* base = NULL; | 246 | void* base = nullptr; |
| 247 | if (globalbase == NULL){ | 247 | if (globalbase == nullptr){ |
| 248 | base = mmap(0, 0x08000000, PROT_READ | PROT_WRITE, | 248 | base = mmap(0, 0x08000000, PROT_READ | PROT_WRITE, |
| 249 | MAP_ANON | MAP_SHARED, -1, 0); | 249 | MAP_ANON | MAP_SHARED, -1, 0); |
| 250 | if (base == MAP_FAILED) { | 250 | if (base == MAP_FAILED) { |
| @@ -357,7 +357,7 @@ bail: | |||
| 357 | if (views[j].out_ptr_low && *views[j].out_ptr_low) | 357 | if (views[j].out_ptr_low && *views[j].out_ptr_low) |
| 358 | { | 358 | { |
| 359 | arena->ReleaseView(*views[j].out_ptr_low, views[j].size); | 359 | arena->ReleaseView(*views[j].out_ptr_low, views[j].size); |
| 360 | *views[j].out_ptr_low = NULL; | 360 | *views[j].out_ptr_low = nullptr; |
| 361 | } | 361 | } |
| 362 | if (*views[j].out_ptr) | 362 | if (*views[j].out_ptr) |
| 363 | { | 363 | { |
| @@ -369,7 +369,7 @@ bail: | |||
| 369 | arena->ReleaseView(*views[j].out_ptr, views[j].size); | 369 | arena->ReleaseView(*views[j].out_ptr, views[j].size); |
| 370 | } | 370 | } |
| 371 | #endif | 371 | #endif |
| 372 | *views[j].out_ptr = NULL; | 372 | *views[j].out_ptr = nullptr; |
| 373 | } | 373 | } |
| 374 | } | 374 | } |
| 375 | return false; | 375 | return false; |
| @@ -415,7 +415,7 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena | |||
| 415 | #elif defined(_WIN32) | 415 | #elif defined(_WIN32) |
| 416 | // Try a whole range of possible bases. Return once we got a valid one. | 416 | // Try a whole range of possible bases. Return once we got a valid one. |
| 417 | u32 max_base_addr = 0x7FFF0000 - 0x10000000; | 417 | u32 max_base_addr = 0x7FFF0000 - 0x10000000; |
| 418 | u8 *base = NULL; | 418 | u8 *base = nullptr; |
| 419 | 419 | ||
| 420 | for (u32 base_addr = 0x01000000; base_addr < max_base_addr; base_addr += 0x400000) | 420 | for (u32 base_addr = 0x01000000; base_addr < max_base_addr; base_addr += 0x400000) |
| 421 | { | 421 | { |
| @@ -423,7 +423,7 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena | |||
| 423 | base = (u8 *)base_addr; | 423 | base = (u8 *)base_addr; |
| 424 | if (Memory_TryBase(base, views, num_views, flags, arena)) | 424 | if (Memory_TryBase(base, views, num_views, flags, arena)) |
| 425 | { | 425 | { |
| 426 | INFO_LOG(MEMMAP, "Found valid memory base at %p after %i tries.", base, base_attempts); | 426 | LOG_DEBUG(Common_Memory, "Found valid memory base at %p after %i tries.", base, base_attempts); |
| 427 | base_attempts = 0; | 427 | base_attempts = 0; |
| 428 | break; | 428 | break; |
| 429 | } | 429 | } |
| @@ -442,7 +442,7 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena | |||
| 442 | u8 *base = MemArena::Find4GBBase(); | 442 | u8 *base = MemArena::Find4GBBase(); |
| 443 | if (!Memory_TryBase(base, views, num_views, flags, arena)) | 443 | if (!Memory_TryBase(base, views, num_views, flags, arena)) |
| 444 | { | 444 | { |
| 445 | ERROR_LOG(MEMMAP, "MemoryMap_Setup: Failed finding a memory base."); | 445 | LOG_ERROR(Common_Memory, "MemoryMap_Setup: Failed finding a memory base."); |
| 446 | PanicAlert("MemoryMap_Setup: Failed finding a memory base."); | 446 | PanicAlert("MemoryMap_Setup: Failed finding a memory base."); |
| 447 | return 0; | 447 | return 0; |
| 448 | } | 448 | } |
| @@ -463,8 +463,8 @@ void MemoryMap_Shutdown(const MemoryView *views, int num_views, u32 flags, MemAr | |||
| 463 | arena->ReleaseView(*views[i].out_ptr_low, views[i].size); | 463 | arena->ReleaseView(*views[i].out_ptr_low, views[i].size); |
| 464 | if (*views[i].out_ptr && (views[i].out_ptr_low && *views[i].out_ptr != *views[i].out_ptr_low)) | 464 | if (*views[i].out_ptr && (views[i].out_ptr_low && *views[i].out_ptr != *views[i].out_ptr_low)) |
| 465 | arena->ReleaseView(*views[i].out_ptr, views[i].size); | 465 | arena->ReleaseView(*views[i].out_ptr, views[i].size); |
| 466 | *views[i].out_ptr = NULL; | 466 | *views[i].out_ptr = nullptr; |
| 467 | if (views[i].out_ptr_low) | 467 | if (views[i].out_ptr_low) |
| 468 | *views[i].out_ptr_low = NULL; | 468 | *views[i].out_ptr_low = nullptr; |
| 469 | } | 469 | } |
| 470 | } | 470 | } |
diff --git a/src/common/memory_util.cpp b/src/common/memory_util.cpp index b6f66e4e1..8f982da89 100644 --- a/src/common/memory_util.cpp +++ b/src/common/memory_util.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | 5 | ||
| @@ -93,7 +93,7 @@ void* AllocateMemoryPages(size_t size) | |||
| 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 == nullptr) |
| 97 | PanicAlert("Failed to allocate raw memory"); | 97 | PanicAlert("Failed to allocate raw memory"); |
| 98 | 98 | ||
| 99 | return ptr; | 99 | return ptr; |
| @@ -104,19 +104,19 @@ void* AllocateAlignedMemory(size_t size,size_t alignment) | |||
| 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 = nullptr; |
| 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 | LOG_ERROR(Common_Memory, "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 == nullptr) |
| 120 | PanicAlert("Failed to allocate aligned memory"); | 120 | PanicAlert("Failed to allocate aligned memory"); |
| 121 | 121 | ||
| 122 | return ptr; | 122 | return ptr; |
| @@ -130,7 +130,7 @@ void FreeMemoryPages(void* ptr, size_t size) | |||
| 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 = nullptr; // Is this our responsibility? |
| 134 | 134 | ||
| 135 | #else | 135 | #else |
| 136 | munmap(ptr, size); | 136 | munmap(ptr, size); |
| @@ -184,7 +184,7 @@ std::string MemUsage() | |||
| 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 (nullptr == hProcess) return "MemUsage Error"; |
| 188 | 188 | ||
| 189 | if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) | 189 | if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) |
| 190 | Ret = Common::StringFromFormat("%s K", Common::ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); | 190 | Ret = Common::StringFromFormat("%s K", Common::ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); |
diff --git a/src/common/memory_util.h b/src/common/memory_util.h index 922bd44b2..9fdbf1f12 100644 --- a/src/common/memory_util.h +++ b/src/common/memory_util.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/misc.cpp b/src/common/misc.cpp index cf6df44e8..e33055d10 100644 --- a/src/common/misc.cpp +++ b/src/common/misc.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/common.h" | 5 | #include "common/common.h" |
| @@ -23,9 +23,9 @@ const char* GetLastErrorMsg() | |||
| 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, nullptr, GetLastError(), |
| 27 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | 27 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
| 28 | err_str, buff_size, NULL); | 28 | err_str, buff_size, nullptr); |
| 29 | #else | 29 | #else |
| 30 | static __thread char err_str[buff_size] = {}; | 30 | static __thread char err_str[buff_size] = {}; |
| 31 | 31 | ||
diff --git a/src/common/msg_handler.cpp b/src/common/msg_handler.cpp index b3556aaa8..4a47b518e 100644 --- a/src/common/msg_handler.cpp +++ b/src/common/msg_handler.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cstdio> | 5 | #include <cstdio> |
| @@ -75,7 +75,7 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...) | |||
| 75 | Common::CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args); | 75 | Common::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 | LOG_INFO(Common, "%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)) |
diff --git a/src/common/msg_handler.h b/src/common/msg_handler.h index a1db89aa3..b4f380782 100644 --- a/src/common/msg_handler.h +++ b/src/common/msg_handler.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/platform.h b/src/common/platform.h index 7d123caa0..ce5550520 100644 --- a/src/common/platform.h +++ b/src/common/platform.h | |||
| @@ -80,7 +80,7 @@ | |||
| 80 | inline struct tm* localtime_r(const time_t *clock, struct tm *result) { | 80 | inline struct tm* localtime_r(const time_t *clock, struct tm *result) { |
| 81 | if (localtime_s(result, clock) == 0) | 81 | if (localtime_s(result, clock) == 0) |
| 82 | return result; | 82 | return result; |
| 83 | return NULL; | 83 | return nullptr; |
| 84 | } | 84 | } |
| 85 | #endif | 85 | #endif |
| 86 | 86 | ||
diff --git a/src/common/scm_rev.h b/src/common/scm_rev.h index d34664614..0ef190afa 100644 --- a/src/common/scm_rev.h +++ b/src/common/scm_rev.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/scope_exit.h b/src/common/scope_exit.h new file mode 100644 index 000000000..263beaf0e --- /dev/null +++ b/src/common/scope_exit.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace detail { | ||
| 8 | template <typename Func> | ||
| 9 | struct ScopeExitHelper { | ||
| 10 | explicit ScopeExitHelper(Func&& func) : func(std::move(func)) {} | ||
| 11 | ~ScopeExitHelper() { func(); } | ||
| 12 | |||
| 13 | Func func; | ||
| 14 | }; | ||
| 15 | |||
| 16 | template <typename Func> | ||
| 17 | ScopeExitHelper<Func> ScopeExit(Func&& func) { return ScopeExitHelper<Func>(std::move(func)); } | ||
| 18 | } | ||
| 19 | |||
| 20 | /** | ||
| 21 | * This macro allows you to conveniently specify a block of code that will run on scope exit. Handy | ||
| 22 | * for doing ad-hoc clean-up tasks in a function with multiple returns. | ||
| 23 | * | ||
| 24 | * Example usage: | ||
| 25 | * \code | ||
| 26 | * const int saved_val = g_foo; | ||
| 27 | * g_foo = 55; | ||
| 28 | * SCOPE_EXIT({ g_foo = saved_val; }); | ||
| 29 | * | ||
| 30 | * if (Bar()) { | ||
| 31 | * return 0; | ||
| 32 | * } else { | ||
| 33 | * return 20; | ||
| 34 | * } | ||
| 35 | * \endcode | ||
| 36 | */ | ||
| 37 | #define SCOPE_EXIT(body) auto scope_exit_helper_##__LINE__ = detail::ScopeExit([&]() body) | ||
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 1ca2dfb39..0dd2d2349 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <boost/range/algorithm.hpp> |
| 6 | 6 | ||
| 7 | #include "common/common.h" | 7 | #include "common/common.h" |
| 8 | #include "common/string_util.h" | 8 | #include "common/string_util.h" |
| @@ -18,20 +18,20 @@ namespace Common { | |||
| 18 | 18 | ||
| 19 | /// Make a string lowercase | 19 | /// Make a string lowercase |
| 20 | std::string ToLower(std::string str) { | 20 | std::string ToLower(std::string str) { |
| 21 | std::transform(str.begin(), str.end(), str.begin(), ::tolower); | 21 | boost::transform(str, str.begin(), ::tolower); |
| 22 | return str; | 22 | return str; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | /// Make a string uppercase | 25 | /// Make a string uppercase |
| 26 | std::string ToUpper(std::string str) { | 26 | std::string ToUpper(std::string str) { |
| 27 | std::transform(str.begin(), str.end(), str.begin(), ::toupper); | 27 | boost::transform(str, str.begin(), ::toupper); |
| 28 | return str; | 28 | return str; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | // faster than sscanf | 31 | // faster than sscanf |
| 32 | bool AsciiToHex(const char* _szValue, u32& result) | 32 | bool AsciiToHex(const char* _szValue, u32& result) |
| 33 | { | 33 | { |
| 34 | char *endptr = NULL; | 34 | char *endptr = nullptr; |
| 35 | const u32 value = strtoul(_szValue, &endptr, 16); | 35 | const u32 value = strtoul(_szValue, &endptr, 16); |
| 36 | 36 | ||
| 37 | if (!endptr || *endptr) | 37 | if (!endptr || *endptr) |
| @@ -69,7 +69,7 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar | |||
| 69 | // will be present in the middle of a multibyte sequence. | 69 | // will be present in the middle of a multibyte sequence. |
| 70 | // | 70 | // |
| 71 | // This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l. | 71 | // This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l. |
| 72 | static locale_t c_locale = NULL; | 72 | static locale_t c_locale = nullptr; |
| 73 | if (!c_locale) | 73 | if (!c_locale) |
| 74 | c_locale = _create_locale(LC_ALL, ".1252"); | 74 | c_locale = _create_locale(LC_ALL, ".1252"); |
| 75 | writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); | 75 | writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); |
| @@ -92,7 +92,7 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar | |||
| 92 | std::string StringFromFormat(const char* format, ...) | 92 | std::string StringFromFormat(const char* format, ...) |
| 93 | { | 93 | { |
| 94 | va_list args; | 94 | va_list args; |
| 95 | char *buf = NULL; | 95 | char *buf = nullptr; |
| 96 | #ifdef _WIN32 | 96 | #ifdef _WIN32 |
| 97 | int required = 0; | 97 | int required = 0; |
| 98 | 98 | ||
| @@ -107,7 +107,7 @@ std::string StringFromFormat(const char* format, ...) | |||
| 107 | #else | 107 | #else |
| 108 | va_start(args, format); | 108 | va_start(args, format); |
| 109 | if (vasprintf(&buf, format, args) < 0) | 109 | if (vasprintf(&buf, format, args) < 0) |
| 110 | ERROR_LOG(COMMON, "Unable to allocate memory for string"); | 110 | LOG_ERROR(Common, "Unable to allocate memory for string"); |
| 111 | va_end(args); | 111 | va_end(args); |
| 112 | 112 | ||
| 113 | std::string temp = buf; | 113 | std::string temp = buf; |
| @@ -162,7 +162,7 @@ std::string StripQuotes(const std::string& s) | |||
| 162 | 162 | ||
| 163 | bool TryParse(const std::string &str, u32 *const output) | 163 | bool TryParse(const std::string &str, u32 *const output) |
| 164 | { | 164 | { |
| 165 | char *endptr = NULL; | 165 | char *endptr = nullptr; |
| 166 | 166 | ||
| 167 | // Reset errno to a value other than ERANGE | 167 | // Reset errno to a value other than ERANGE |
| 168 | errno = 0; | 168 | errno = 0; |
| @@ -475,7 +475,7 @@ static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& | |||
| 475 | iconv_t const conv_desc = iconv_open("UTF-8", fromcode); | 475 | iconv_t const conv_desc = iconv_open("UTF-8", fromcode); |
| 476 | if ((iconv_t)(-1) == conv_desc) | 476 | if ((iconv_t)(-1) == conv_desc) |
| 477 | { | 477 | { |
| 478 | ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno)); | 478 | LOG_ERROR(Common, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno)); |
| 479 | iconv_close(conv_desc); | 479 | iconv_close(conv_desc); |
| 480 | return {}; | 480 | return {}; |
| 481 | } | 481 | } |
| @@ -510,7 +510,7 @@ static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& | |||
| 510 | } | 510 | } |
| 511 | else | 511 | else |
| 512 | { | 512 | { |
| 513 | ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno)); | 513 | LOG_ERROR(Common, "iconv failure [%s]: %s", fromcode, strerror(errno)); |
| 514 | break; | 514 | break; |
| 515 | } | 515 | } |
| 516 | } | 516 | } |
| @@ -528,10 +528,10 @@ std::u16string UTF8ToUTF16(const std::string& input) | |||
| 528 | { | 528 | { |
| 529 | std::u16string result; | 529 | std::u16string result; |
| 530 | 530 | ||
| 531 | iconv_t const conv_desc = iconv_open("UTF-16", "UTF-8"); | 531 | iconv_t const conv_desc = iconv_open("UTF-16LE", "UTF-8"); |
| 532 | if ((iconv_t)(-1) == conv_desc) | 532 | if ((iconv_t)(-1) == conv_desc) |
| 533 | { | 533 | { |
| 534 | ERROR_LOG(COMMON, "Iconv initialization failure [UTF-8]: %s", strerror(errno)); | 534 | LOG_ERROR(Common, "Iconv initialization failure [UTF-8]: %s", strerror(errno)); |
| 535 | iconv_close(conv_desc); | 535 | iconv_close(conv_desc); |
| 536 | return {}; | 536 | return {}; |
| 537 | } | 537 | } |
| @@ -566,7 +566,7 @@ std::u16string UTF8ToUTF16(const std::string& input) | |||
| 566 | } | 566 | } |
| 567 | else | 567 | else |
| 568 | { | 568 | { |
| 569 | ERROR_LOG(COMMON, "iconv failure [UTF-8]: %s", strerror(errno)); | 569 | LOG_ERROR(Common, "iconv failure [UTF-8]: %s", strerror(errno)); |
| 570 | break; | 570 | break; |
| 571 | } | 571 | } |
| 572 | } | 572 | } |
| @@ -582,7 +582,7 @@ std::u16string UTF8ToUTF16(const std::string& input) | |||
| 582 | 582 | ||
| 583 | std::string UTF16ToUTF8(const std::u16string& input) | 583 | std::string UTF16ToUTF8(const std::u16string& input) |
| 584 | { | 584 | { |
| 585 | return CodeToUTF8("UTF-16", input); | 585 | return CodeToUTF8("UTF-16LE", input); |
| 586 | } | 586 | } |
| 587 | 587 | ||
| 588 | std::string CP1252ToUTF8(const std::string& input) | 588 | std::string CP1252ToUTF8(const std::string& input) |
diff --git a/src/common/string_util.h b/src/common/string_util.h index ae5bbadad..74974263f 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| @@ -115,4 +115,19 @@ inline std::string UTF8ToTStr(const std::string& str) | |||
| 115 | 115 | ||
| 116 | #endif | 116 | #endif |
| 117 | 117 | ||
| 118 | /** | ||
| 119 | * Compares the string defined by the range [`begin`, `end`) to the null-terminated C-string | ||
| 120 | * `other` for equality. | ||
| 121 | */ | ||
| 122 | template <typename InIt> | ||
| 123 | bool ComparePartialString(InIt begin, InIt end, const char* other) { | ||
| 124 | for (; begin != end && *other != '\0'; ++begin, ++other) { | ||
| 125 | if (*begin != *other) { | ||
| 126 | return false; | ||
| 127 | } | ||
| 128 | } | ||
| 129 | // Only return true if both strings finished at the same point | ||
| 130 | return (begin == end) == (*other == '\0'); | ||
| 131 | } | ||
| 132 | |||
| 118 | } | 133 | } |
diff --git a/src/common/symbols.cpp b/src/common/symbols.cpp index 63ad6218b..9e4dccfb3 100644 --- a/src/common/symbols.cpp +++ b/src/common/symbols.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/symbols.h" | 5 | #include "common/symbols.h" |
diff --git a/src/common/symbols.h b/src/common/symbols.h index 4560f5240..f76cb6b1e 100644 --- a/src/common/symbols.h +++ b/src/common/symbols.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/thread.cpp b/src/common/thread.cpp index 6eeda0828..04e33101b 100644 --- a/src/common/thread.cpp +++ b/src/common/thread.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/thread.h" | 5 | #include "common/thread.h" |
diff --git a/src/common/thread.h b/src/common/thread.h index be9b5cbe2..eaf1ba00c 100644 --- a/src/common/thread.h +++ b/src/common/thread.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| @@ -21,6 +21,7 @@ | |||
| 21 | //for gettimeofday and struct time(spec|val) | 21 | //for gettimeofday and struct time(spec|val) |
| 22 | #include <time.h> | 22 | #include <time.h> |
| 23 | #include <sys/time.h> | 23 | #include <sys/time.h> |
| 24 | #include <unistd.h> | ||
| 24 | #endif | 25 | #endif |
| 25 | 26 | ||
| 26 | namespace Common | 27 | namespace Common |
diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 59efbce4c..4e1c0a215 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project / PPSSPP Project | 1 | // Copyright 2014 Citra Emulator Project / PPSSPP Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| @@ -37,7 +37,7 @@ struct ThreadQueueList { | |||
| 37 | ~ThreadQueueList() { | 37 | ~ThreadQueueList() { |
| 38 | for (int i = 0; i < NUM_QUEUES; ++i) | 38 | for (int i = 0; i < NUM_QUEUES; ++i) |
| 39 | { | 39 | { |
| 40 | if (queues[i].data != NULL) | 40 | if (queues[i].data != nullptr) |
| 41 | free(queues[i].data); | 41 | free(queues[i].data); |
| 42 | } | 42 | } |
| 43 | } | 43 | } |
| @@ -46,7 +46,7 @@ struct ThreadQueueList { | |||
| 46 | int contains(const IdType uid) { | 46 | int contains(const IdType uid) { |
| 47 | for (int i = 0; i < NUM_QUEUES; ++i) | 47 | for (int i = 0; i < NUM_QUEUES; ++i) |
| 48 | { | 48 | { |
| 49 | if (queues[i].data == NULL) | 49 | if (queues[i].data == nullptr) |
| 50 | continue; | 50 | continue; |
| 51 | 51 | ||
| 52 | Queue *cur = &queues[i]; | 52 | Queue *cur = &queues[i]; |
| @@ -133,7 +133,7 @@ struct ThreadQueueList { | |||
| 133 | inline void clear() { | 133 | inline void clear() { |
| 134 | for (int i = 0; i < NUM_QUEUES; ++i) | 134 | for (int i = 0; i < NUM_QUEUES; ++i) |
| 135 | { | 135 | { |
| 136 | if (queues[i].data != NULL) | 136 | if (queues[i].data != nullptr) |
| 137 | free(queues[i].data); | 137 | free(queues[i].data); |
| 138 | } | 138 | } |
| 139 | memset(queues, 0, sizeof(queues)); | 139 | memset(queues, 0, sizeof(queues)); |
| @@ -147,7 +147,7 @@ struct ThreadQueueList { | |||
| 147 | 147 | ||
| 148 | inline void prepare(u32 priority) { | 148 | inline void prepare(u32 priority) { |
| 149 | Queue *cur = &queues[priority]; | 149 | Queue *cur = &queues[priority]; |
| 150 | if (cur->next == NULL) | 150 | if (cur->next == nullptr) |
| 151 | link(priority, INITIAL_CAPACITY); | 151 | link(priority, INITIAL_CAPACITY); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| @@ -176,7 +176,7 @@ private: | |||
| 176 | 176 | ||
| 177 | for (int i = (int) priority - 1; i >= 0; --i) | 177 | for (int i = (int) priority - 1; i >= 0; --i) |
| 178 | { | 178 | { |
| 179 | if (queues[i].next != NULL) | 179 | if (queues[i].next != nullptr) |
| 180 | { | 180 | { |
| 181 | cur->next = queues[i].next; | 181 | cur->next = queues[i].next; |
| 182 | queues[i].next = cur; | 182 | queues[i].next = cur; |
| @@ -193,7 +193,7 @@ private: | |||
| 193 | int size = cur->end - cur->first; | 193 | int size = cur->end - cur->first; |
| 194 | if (size >= cur->capacity - 2) { | 194 | if (size >= cur->capacity - 2) { |
| 195 | IdType *new_data = (IdType *)realloc(cur->data, cur->capacity * 2 * sizeof(IdType)); | 195 | IdType *new_data = (IdType *)realloc(cur->data, cur->capacity * 2 * sizeof(IdType)); |
| 196 | if (new_data != NULL) { | 196 | if (new_data != nullptr) { |
| 197 | cur->capacity *= 2; | 197 | cur->capacity *= 2; |
| 198 | cur->data = new_data; | 198 | cur->data = new_data; |
| 199 | } | 199 | } |
diff --git a/src/common/thunk.h b/src/common/thunk.h index 90c8be888..4fb7c98e1 100644 --- a/src/common/thunk.h +++ b/src/common/thunk.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/timer.cpp b/src/common/timer.cpp index ded4a344e..a6682ea19 100644 --- a/src/common/timer.cpp +++ b/src/common/timer.cpp | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <time.h> | 5 | #include <time.h> |
| @@ -25,7 +25,7 @@ u32 Timer::GetTimeMs() | |||
| 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, nullptr); |
| 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 | } |
| @@ -183,7 +183,7 @@ std::string Timer::GetTimeFormatted() | |||
| 183 | return StringFromFormat("%s:%03i", tmp, tp.millitm); | 183 | return StringFromFormat("%s:%03i", tmp, tp.millitm); |
| 184 | #else | 184 | #else |
| 185 | struct timeval t; | 185 | struct timeval t; |
| 186 | (void)gettimeofday(&t, NULL); | 186 | (void)gettimeofday(&t, nullptr); |
| 187 | return StringFromFormat("%s:%03d", tmp, (int)(t.tv_usec / 1000)); | 187 | return StringFromFormat("%s:%03d", tmp, (int)(t.tv_usec / 1000)); |
| 188 | #endif | 188 | #endif |
| 189 | } | 189 | } |
| @@ -197,7 +197,7 @@ double Timer::GetDoubleTime() | |||
| 197 | (void)::ftime(&tp); | 197 | (void)::ftime(&tp); |
| 198 | #else | 198 | #else |
| 199 | struct timeval t; | 199 | struct timeval t; |
| 200 | (void)gettimeofday(&t, NULL); | 200 | (void)gettimeofday(&t, nullptr); |
| 201 | #endif | 201 | #endif |
| 202 | // Get continuous timestamp | 202 | // Get continuous timestamp |
| 203 | u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); | 203 | u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); |
diff --git a/src/common/timer.h b/src/common/timer.h index 86418e7a7..4b44c33a0 100644 --- a/src/common/timer.h +++ b/src/common/timer.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
diff --git a/src/common/utf8.cpp b/src/common/utf8.cpp index be4ebc855..66a2f6339 100644 --- a/src/common/utf8.cpp +++ b/src/common/utf8.cpp | |||
| @@ -281,28 +281,28 @@ int u8_read_escape_sequence(const char *str, u32 *dest) | |||
| 281 | do { | 281 | do { |
| 282 | digs[dno++] = str[i++]; | 282 | digs[dno++] = str[i++]; |
| 283 | } while (octal_digit(str[i]) && dno < 3); | 283 | } while (octal_digit(str[i]) && dno < 3); |
| 284 | ch = strtol(digs, NULL, 8); | 284 | ch = strtol(digs, nullptr, 8); |
| 285 | } | 285 | } |
| 286 | else if (str[0] == 'x') { | 286 | else if (str[0] == 'x') { |
| 287 | while (hex_digit(str[i]) && dno < 2) { | 287 | while (hex_digit(str[i]) && dno < 2) { |
| 288 | digs[dno++] = str[i++]; | 288 | digs[dno++] = str[i++]; |
| 289 | } | 289 | } |
| 290 | if (dno > 0) | 290 | if (dno > 0) |
| 291 | ch = strtol(digs, NULL, 16); | 291 | ch = strtol(digs, nullptr, 16); |
| 292 | } | 292 | } |
| 293 | else if (str[0] == 'u') { | 293 | else if (str[0] == 'u') { |
| 294 | while (hex_digit(str[i]) && dno < 4) { | 294 | while (hex_digit(str[i]) && dno < 4) { |
| 295 | digs[dno++] = str[i++]; | 295 | digs[dno++] = str[i++]; |
| 296 | } | 296 | } |
| 297 | if (dno > 0) | 297 | if (dno > 0) |
| 298 | ch = strtol(digs, NULL, 16); | 298 | ch = strtol(digs, nullptr, 16); |
| 299 | } | 299 | } |
| 300 | else if (str[0] == 'U') { | 300 | else if (str[0] == 'U') { |
| 301 | while (hex_digit(str[i]) && dno < 8) { | 301 | while (hex_digit(str[i]) && dno < 8) { |
| 302 | digs[dno++] = str[i++]; | 302 | digs[dno++] = str[i++]; |
| 303 | } | 303 | } |
| 304 | if (dno > 0) | 304 | if (dno > 0) |
| 305 | ch = strtol(digs, NULL, 16); | 305 | ch = strtol(digs, nullptr, 16); |
| 306 | } | 306 | } |
| 307 | *dest = ch; | 307 | *dest = ch; |
| 308 | 308 | ||
| @@ -353,7 +353,7 @@ const char *u8_strchr(const char *s, u32 ch, int *charn) | |||
| 353 | lasti = i; | 353 | lasti = i; |
| 354 | (*charn)++; | 354 | (*charn)++; |
| 355 | } | 355 | } |
| 356 | return NULL; | 356 | return nullptr; |
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | const char *u8_memchr(const char *s, u32 ch, size_t sz, int *charn) | 359 | const char *u8_memchr(const char *s, u32 ch, size_t sz, int *charn) |
| @@ -378,7 +378,7 @@ const char *u8_memchr(const char *s, u32 ch, size_t sz, int *charn) | |||
| 378 | lasti = i; | 378 | lasti = i; |
| 379 | (*charn)++; | 379 | (*charn)++; |
| 380 | } | 380 | } |
| 381 | return NULL; | 381 | return nullptr; |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | int u8_is_locale_utf8(const char *locale) | 384 | int u8_is_locale_utf8(const char *locale) |
| @@ -419,35 +419,35 @@ bool UTF8StringHasNonASCII(const char *utf8string) { | |||
| 419 | 419 | ||
| 420 | std::string ConvertWStringToUTF8(const wchar_t *wstr) { | 420 | std::string ConvertWStringToUTF8(const wchar_t *wstr) { |
| 421 | int len = (int)wcslen(wstr); | 421 | int len = (int)wcslen(wstr); |
| 422 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, NULL, NULL); | 422 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, nullptr, nullptr); |
| 423 | std::string s; | 423 | std::string s; |
| 424 | s.resize(size); | 424 | s.resize(size); |
| 425 | if (size > 0) { | 425 | if (size > 0) { |
| 426 | WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, NULL, NULL); | 426 | WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, nullptr, nullptr); |
| 427 | } | 427 | } |
| 428 | return s; | 428 | return s; |
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | std::string ConvertWStringToUTF8(const std::wstring &wstr) { | 431 | std::string ConvertWStringToUTF8(const std::wstring &wstr) { |
| 432 | int len = (int)wstr.size(); | 432 | int len = (int)wstr.size(); |
| 433 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL); | 433 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, nullptr, nullptr); |
| 434 | std::string s; | 434 | std::string s; |
| 435 | s.resize(size); | 435 | s.resize(size); |
| 436 | if (size > 0) { | 436 | if (size > 0) { |
| 437 | WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, NULL, NULL); | 437 | WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, nullptr, nullptr); |
| 438 | } | 438 | } |
| 439 | return s; | 439 | return s; |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { | 442 | void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { |
| 443 | int len = (int)source.size(); | 443 | int len = (int)source.size(); |
| 444 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); | 444 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, nullptr, 0); |
| 445 | MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size)); | 445 | MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size)); |
| 446 | } | 446 | } |
| 447 | 447 | ||
| 448 | std::wstring ConvertUTF8ToWString(const std::string &source) { | 448 | std::wstring ConvertUTF8ToWString(const std::string &source) { |
| 449 | int len = (int)source.size(); | 449 | int len = (int)source.size(); |
| 450 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); | 450 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, nullptr, 0); |
| 451 | std::wstring str; | 451 | std::wstring str; |
| 452 | str.resize(size); | 452 | str.resize(size); |
| 453 | if (size > 0) { | 453 | if (size > 0) { |