diff --git a/.gitignore b/.gitignore index b821850..8cae565 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ make.bat Tools/updateVersion.pyo build/* .vscode +.vs external/log_install_* BlueFrameworkConfig.cmake BlueFrameworkConfigVersion.cmake +out +CMakeSettings.json \ No newline at end of file diff --git a/Application/CMakeLists.txt b/Application/CMakeLists.txt index e374086..6778aa7 100644 --- a/Application/CMakeLists.txt +++ b/Application/CMakeLists.txt @@ -16,19 +16,20 @@ # along with this program. If not, see . # -add_definitions(-DNOMINMAX) -add_definitions(-DBLUEFRAMEWORK_EXPORT) - # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) # Instruct CMake to run moc automatically when needed. set(CMAKE_AUTOMOC ON) # Unicode rules! -add_definitions(-D_UNICODE -DQT_NO_KEYWORDS) +add_compile_definitions( + BLUEFRAMEWORK_EXPORT + QT_NO_KEYWORDS +) + if (WIN32) # TODO: for now this only works on windows. Change BlueApplication.h to support GCC - add_definitions(-DBLUEAPPLICATION_EXPORT) + add_compile_definitions(BLUEAPPLICATION_EXPORT) endif(WIN32) file(GLOB BlueFramework_Application_Data_Source src/BlueFramework/Application/Data/*.*) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31d6a12..d4b17b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ cmake_minimum_required(VERSION 3.14.3) # Kittens will die if you switch to an earlier version of CMake. cmake_policy(VERSION 3.14.3) -project(BlueFramework) +project(BlueFramework CXX) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake/) include(ProjectVersion) @@ -37,6 +37,11 @@ if(MSVC_VERSION EQUAL 1900) elseif(MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS_EQUAL 1919) set(MSVC_VERSION_STRING "vs2017") set(MSVC_VERSION_YEAR "2017") + set(CMAKE_CXX_STANDARD 17) +elseif(MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS_EQUAL 1930) + set(MSVC_VERSION_STRING "vs2019") + set(MSVC_VERSION_YEAR "2019") + set(CMAKE_CXX_STANDARD 20) else() message(${MSVC_VERSION}) message("Please switch to Visual Studio 14 2015 or Visual Studio 15 2017.") @@ -81,7 +86,7 @@ else() file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/MinSizeRel) endif() -option(BLUEFRAMEWORK_USE_PREDEFINED_THIRDPARTY_PATH "Set to ON to set boost, Eigen and Qt path" ON) +option(BLUEFRAMEWORK_USE_PREDEFINED_THIRDPARTY_PATH "Set to ON to set boost, Eigen and Qt path" OFF) if(BLUEFRAMEWORK_USE_PREDEFINED_THIRDPARTY_PATH) # Try to find Boost, Eigen3, Qt5 and other dependencies without user input @@ -115,9 +120,10 @@ set(CMAKE_PDB_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_BINARY_DIR}/MinSizeRel) set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY AUTOGEN_TARGETS_FOLDER AutoMoc) -add_definitions( - -DEIGEN_MPL2_ONLY # Use only MP2 licenced code of Eigen - -D_UNICODE # Unicode rules +add_compile_definitions( + EIGEN_MPL2_ONLY # Use only MP2 licenced code of Eigen + NOMINMAX + _UNICODE # Unicode rules https://docs.microsoft.com/en-us/cpp/text/unicode-programming-summary?view=msvc-160 ) set(CMAKE_DEBUG_POSTFIX "d") @@ -130,23 +136,15 @@ endif (WIN32) # remember the Kittens... do not switch to earlier versions... set(Boost_USE_STATIC_LIBS ON) -find_package(Boost 1.65.1 COMPONENTS log signals system filesystem REQUIRED) # we suggest Boost 1.65.1 +find_package(Boost 1.75.0 COMPONENTS log system filesystem REQUIRED) # we suggest Boost 1.75.0 FetchContent_Declare( eigen GIT_REPOSITORY https://github.com/eigenteam/eigen-git-mirror.git GIT_TAG 3.3.7 ) - -FetchContent_GetProperties(eigen) -if(NOT eigen_POPULATED) - FetchContent_Populate(eigen) - add_subdirectory(${eigen_SOURCE_DIR} ${eigen_BINARY_DIR} EXCLUDE_FROM_ALL) -endif() - +FetchContent_MakeAvailable(eigen) -#find_package(gtest COMPONENTS gtest gtest_main REQUIRED) -#find_package(TinyXML2 REQUIRED) FetchContent_Declare( tinyxml2 GIT_REPOSITORY https://github.com/leethomason/tinyxml2.git @@ -162,15 +160,10 @@ endif() # find_package(Vulkan REQUIRED) -# We suggest boost 1.64.0 - but 1.63.0 is also fine -if(${Boost_MAJOR_VERSION} EQUAL 1 AND ${Boost_MINOR_VERSION} EQUAL 63 ) - message("Please consider to switch to Boost 1.64.0 or newer") -endif() - # Qt library (do not switch to earlier versions... meow!) cmake_policy(SET CMP0020 NEW) -find_package(Qt5 5.9.0 COMPONENTS Core Widgets Xml XmlPatterns REQUIRED) +find_package(Qt5 5.14.2 COMPONENTS Core Widgets Xml XmlPatterns REQUIRED) if(Qt5_FOUND AND WIN32 AND TARGET Qt5::qmake AND NOT TARGET Qt5::windeployqt) get_target_property(_qt5_qmake_location Qt5::qmake IMPORTED_LOCATION) diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 3ea5d29..05c98da 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -31,6 +31,22 @@ source_group(BlueFramework\\Core\\Math FILES ${BlueFramewo source_group(BlueFramework\\Core\\UtfConverter FILES ${BlueFramework_Core_UtfConverter_Source}) source_group(BlueFramework\\Core FILES ${BlueFramework_Core_Source}) +FetchContent_Declare( + jk_stackwalker + GIT_REPOSITORY https://github.com/JochenKalmbach/StackWalker + GIT_TAG 1.20 +) +FetchContent_MakeAvailable(jk_stackwalker) + +target_compile_definitions(StackWalker PUBLIC _UNICODE) + +FetchContent_Declare( + c42f_tinyformat + GIT_REPOSITORY https://github.com/c42f/tinyformat + GIT_TAG v2.3.0 +) +FetchContent_MakeAvailable(c42f_tinyformat) + add_library(BlueFramework.Core SHARED ${BlueFramework_Core_Diagnostics_IC_Source} ${BlueFramework_Core_Diagnostics_Source} @@ -43,6 +59,8 @@ target_include_directories(BlueFramework.Core PUBLIC ${Boost_INCLUDE_DIR} src + ${jk_stackwalker_SOURCE_DIR}/Main/StackWalker + ${c42f_tinyformat_SOURCE_DIR} ) target_link_libraries(BlueFramework.Core @@ -51,6 +69,7 @@ target_link_libraries(BlueFramework.Core Boost::boost Boost::log eigen + StackWalker ) install(TARGETS BlueFramework.Core diff --git a/Core/src/BlueFramework/Core/Diagnostics/StackWalker.cpp b/Core/src/BlueFramework/Core/Diagnostics/StackWalker.cpp deleted file mode 100644 index 78da9c0..0000000 --- a/Core/src/BlueFramework/Core/Diagnostics/StackWalker.cpp +++ /dev/null @@ -1,1360 +0,0 @@ -/********************************************************************** - * - * StackWalker.cpp - * http://stackwalker.codeplex.com/ - * - * - * History: - * 2005-07-27 v1 - First public release on http://www.codeproject.com/ - * http://www.codeproject.com/threads/StackWalker.asp - * 2005-07-28 v2 - Changed the params of the constructor and ShowCallstack - * (to simplify the usage) - * 2005-08-01 v3 - Changed to use 'CONTEXT_FULL' instead of CONTEXT_ALL - * (should also be enough) - * - Changed to compile correctly with the PSDK of VC7.0 - * (GetFileVersionInfoSizeA and GetFileVersionInfoA is wrongly defined: - * it uses LPSTR instead of LPCSTR as first paremeter) - * - Added declarations to support VC5/6 without using 'dbghelp.h' - * - Added a 'pUserData' member to the ShowCallstack function and the - * PReadProcessMemoryRoutine declaration (to pass some user-defined data, - * which can be used in the readMemoryFunction-callback) - * 2005-08-02 v4 - OnSymInit now also outputs the OS-Version by default - * - Added example for doing an exception-callstack-walking in main.cpp - * (thanks to owillebo: http://www.codeproject.com/script/profile/whos_who.asp?id=536268) - * 2005-08-05 v5 - Removed most Lint (http://www.gimpel.com/) errors... thanks to Okko Willeboordse! - * 2008-08-04 v6 - Fixed Bug: Missing LEAK-end-tag - * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2502890#xx2502890xx - * Fixed Bug: Compiled with "WIN32_LEAN_AND_MEAN" - * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=1824718#xx1824718xx - * Fixed Bug: Compiling with "/Wall" - * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2638243#xx2638243xx - * Fixed Bug: Now checking SymUseSymSrv - * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1388979#xx1388979xx - * Fixed Bug: Support for recursive function calls - * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1434538#xx1434538xx - * Fixed Bug: Missing FreeLibrary call in "GetModuleListTH32" - * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=1326923#xx1326923xx - * Fixed Bug: SymDia is number 7, not 9! - * 2008-09-11 v7 For some (undocumented) reason, dbhelp.h is needing a packing of 8! - * Thanks to Teajay which reported the bug... - * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=2718933#xx2718933xx - * 2008-11-27 v8 Debugging Tools for Windows are now stored in a different directory - * Thanks to Luiz Salamon which reported this "bug"... - * http://www.codeproject.com/KB/threads/StackWalker.aspx?msg=2822736#xx2822736xx - * 2009-04-10 v9 License slihtly corrected ( replaced) - * 2009-11-01 v10 Moved to http://stackwalker.codeplex.com/ - * 2009-11-02 v11 Now try to use IMAGEHLP_MODULE64_V3 if available - * 2010-04-15 v12 Added support for VS2010 RTM - * 2010-05-25 v13 Now using secure MyStrcCpy. Thanks to luke.simon: - * http://www.codeproject.com/KB/applications/leakfinder.aspx?msg=3477467#xx3477467xx - * 2013-01-07 v14 Runtime Check Error VS2010 Debug Builds fixed: - * http://stackwalker.codeplex.com/workitem/10511 - * - * - * LICENSE (http://www.opensource.org/licenses/bsd-license.php) - * - * Copyright (c) 2005-2013, Jochen Kalmbach - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of Jochen Kalmbach nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ -#include -#include -#include -#include -#pragma comment(lib, "version.lib") // for "VerQueryValue" -#pragma warning(disable:4826) - -#include "StackWalker.h" - - -// If VC7 and later, then use the shipped 'dbghelp.h'-file -#pragma pack(push,8) -#if _MSC_VER >= 1300 -#include -#else -// inline the important dbghelp.h-declarations... -typedef enum { - SymNone = 0, - SymCoff, - SymCv, - SymPdb, - SymExport, - SymDeferred, - SymSym, - SymDia, - SymVirtual, - NumSymTypes -} SYM_TYPE; -typedef struct _IMAGEHLP_LINE64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) - PVOID Key; // internal - DWORD LineNumber; // line number in file - PCHAR FileName; // full filename - DWORD64 Address; // first instruction of line -} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; -typedef struct _IMAGEHLP_MODULE64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - CHAR ModuleName[32]; // module name - CHAR ImageName[256]; // image name - CHAR LoadedImageName[256]; // symbol file name -} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; -typedef struct _IMAGEHLP_SYMBOL64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64) - DWORD64 Address; // virtual address including dll base address - DWORD Size; // estimated size of symbol, can be zero - DWORD Flags; // info about the symbols, see the SYMF defines - DWORD MaxNameLength; // maximum size of symbol name in 'Name' - CHAR Name[1]; // symbol name (null terminated string) -} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; -typedef enum { - AddrMode1616, - AddrMode1632, - AddrModeReal, - AddrModeFlat -} ADDRESS_MODE; -typedef struct _tagADDRESS64 { - DWORD64 Offset; - WORD Segment; - ADDRESS_MODE Mode; -} ADDRESS64, *LPADDRESS64; -typedef struct _KDHELP64 { - DWORD64 Thread; - DWORD ThCallbackStack; - DWORD ThCallbackBStore; - DWORD NextCallback; - DWORD FramePointer; - DWORD64 KiCallUserMode; - DWORD64 KeUserCallbackDispatcher; - DWORD64 SystemRangeStart; - DWORD64 Reserved[8]; -} KDHELP64, *PKDHELP64; -typedef struct _tagSTACKFRAME64 { - ADDRESS64 AddrPC; // program counter - ADDRESS64 AddrReturn; // return address - ADDRESS64 AddrFrame; // frame pointer - ADDRESS64 AddrStack; // stack pointer - ADDRESS64 AddrBStore; // backing store pointer - PVOID FuncTableEntry; // pointer to pdata/fpo or NULL - DWORD64 Params[4]; // possible arguments to the function - BOOL Far; // WOW far call - BOOL Virtual; // is this a virtual frame? - DWORD64 Reserved[3]; - KDHELP64 KdHelp; -} STACKFRAME64, *LPSTACKFRAME64; -typedef -BOOL -(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)( - HANDLE hProcess, - DWORD64 qwBaseAddress, - PVOID lpBuffer, - DWORD nSize, - LPDWORD lpNumberOfBytesRead - ); -typedef -PVOID -(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( - HANDLE hProcess, - DWORD64 AddrBase - ); -typedef -DWORD64 -(__stdcall *PGET_MODULE_BASE_ROUTINE64)( - HANDLE hProcess, - DWORD64 Address - ); -typedef -DWORD64 -(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)( - HANDLE hProcess, - HANDLE hThread, - LPADDRESS64 lpaddr - ); -#define SYMOPT_CASE_INSENSITIVE 0x00000001 -#define SYMOPT_UNDNAME 0x00000002 -#define SYMOPT_DEFERRED_LOADS 0x00000004 -#define SYMOPT_NO_CPP 0x00000008 -#define SYMOPT_LOAD_LINES 0x00000010 -#define SYMOPT_OMAP_FIND_NEAREST 0x00000020 -#define SYMOPT_LOAD_ANYTHING 0x00000040 -#define SYMOPT_IGNORE_CVREC 0x00000080 -#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 -#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 -#define SYMOPT_EXACT_SYMBOLS 0x00000400 -#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 -#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 -#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 -#define SYMOPT_PUBLICS_ONLY 0x00004000 -#define SYMOPT_NO_PUBLICS 0x00008000 -#define SYMOPT_AUTO_PUBLICS 0x00010000 -#define SYMOPT_NO_IMAGE_SEARCH 0x00020000 -#define SYMOPT_SECURE 0x00040000 -#define SYMOPT_DEBUG 0x80000000 -#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration -#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; -#endif // _MSC_VER < 1300 -#pragma pack(pop) - -// Some missing defines (for VC5/6): -#ifndef INVALID_FILE_ATTRIBUTES -#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) -#endif - - -// secure-CRT_functions are only available starting with VC8 -#if _MSC_VER < 1400 -#define strcpy_s(dst, len, src) strcpy(dst, src) -#define strncpy_s(dst, len, src, maxLen) strncpy(dst, len, src) -#define strcat_s(dst, len, src) strcat(dst, src) -#define _snprintf_s _snprintf -#define _tcscat_s _tcscat -#endif - -static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc) -{ - if (nMaxDestSize <= 0) return; - strncpy_s(szDest, nMaxDestSize, szSrc, _TRUNCATE); - szDest[nMaxDestSize-1] = 0; // INFO: _TRUNCATE will ensure that it is nul-terminated; but with older compilers (<1400) it uses "strncpy" and this does not!) -} // MyStrCpy - -// Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL') -#define USED_CONTEXT_FLAGS CONTEXT_FULL - - -class StackWalkerInternal -{ -public: - StackWalkerInternal(StackWalker *parent, HANDLE hProcess) - { - m_parent = parent; - m_hDbhHelp = NULL; - pSC = NULL; - m_hProcess = hProcess; - m_szSymPath = NULL; - pSFTA = NULL; - pSGLFA = NULL; - pSGMB = NULL; - pSGMI = NULL; - pSGO = NULL; - pSGSFA = NULL; - pSI = NULL; - pSLM = NULL; - pSSO = NULL; - pSW = NULL; - pUDSN = NULL; - pSGSP = NULL; - } - ~StackWalkerInternal() - { - if (pSC != NULL) - pSC(m_hProcess); // SymCleanup - if (m_hDbhHelp != NULL) - FreeLibrary(m_hDbhHelp); - m_hDbhHelp = NULL; - m_parent = NULL; - if(m_szSymPath != NULL) - free(m_szSymPath); - m_szSymPath = NULL; - } - BOOL Init(LPCSTR szSymPath) - { - if (m_parent == NULL) - return FALSE; - // Dynamically load the Entry-Points for dbghelp.dll: - // First try to load the newsest one from - TCHAR szTemp[4096]; - // But before wqe do this, we first check if the ".local" file exists - if (GetModuleFileName(NULL, szTemp, 4096) > 0) - { - _tcscat_s(szTemp, _T(".local")); - if (GetFileAttributes(szTemp) == INVALID_FILE_ATTRIBUTES) - { - // ".local" file does not exist, so we can try to load the dbghelp.dll from the "Debugging Tools for Windows" - // Ok, first try the new path according to the archtitecture: -#ifdef _M_IX86 - if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) - { - _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x86)\\dbghelp.dll")); - // now check if the file exists: - if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) - { - m_hDbhHelp = LoadLibrary(szTemp); - } - } -#elif _M_X64 - if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) - { - _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll")); - // now check if the file exists: - if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) - { - m_hDbhHelp = LoadLibrary(szTemp); - } - } -#elif _M_IA64 - if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) - { - _tcscat_s(szTemp, _T("\\Debugging Tools for Windows (ia64)\\dbghelp.dll")); - // now check if the file exists: - if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) - { - m_hDbhHelp = LoadLibrary(szTemp); - } - } -#endif - // If still not found, try the old directories... - if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) - { - _tcscat_s(szTemp, _T("\\Debugging Tools for Windows\\dbghelp.dll")); - // now check if the file exists: - if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) - { - m_hDbhHelp = LoadLibrary(szTemp); - } - } -#if defined _M_X64 || defined _M_IA64 - // Still not found? Then try to load the (old) 64-Bit version: - if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) ) - { - _tcscat_s(szTemp, _T("\\Debugging Tools for Windows 64-Bit\\dbghelp.dll")); - if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES) - { - m_hDbhHelp = LoadLibrary(szTemp); - } - } -#endif - } - } - if (m_hDbhHelp == NULL) // if not already loaded, try to load a default-one - m_hDbhHelp = LoadLibrary( _T("dbghelp.dll") ); - if (m_hDbhHelp == NULL) - return FALSE; - pSI = (tSI) GetProcAddress(m_hDbhHelp, "SymInitialize" ); - pSC = (tSC) GetProcAddress(m_hDbhHelp, "SymCleanup" ); - - pSW = (tSW) GetProcAddress(m_hDbhHelp, "StackWalk64" ); - pSGO = (tSGO) GetProcAddress(m_hDbhHelp, "SymGetOptions" ); - pSSO = (tSSO) GetProcAddress(m_hDbhHelp, "SymSetOptions" ); - - pSFTA = (tSFTA) GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64" ); - pSGLFA = (tSGLFA) GetProcAddress(m_hDbhHelp, "SymGetLineFromAddr64" ); - pSGMB = (tSGMB) GetProcAddress(m_hDbhHelp, "SymGetModuleBase64" ); - pSGMI = (tSGMI) GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64" ); - pSGSFA = (tSGSFA) GetProcAddress(m_hDbhHelp, "SymGetSymFromAddr64" ); - pUDSN = (tUDSN) GetProcAddress(m_hDbhHelp, "UnDecorateSymbolName" ); - pSLM = (tSLM) GetProcAddress(m_hDbhHelp, "SymLoadModule64" ); - pSGSP =(tSGSP) GetProcAddress(m_hDbhHelp, "SymGetSearchPath" ); - - if ( pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL || - pSGO == NULL || pSGSFA == NULL || pSI == NULL || pSSO == NULL || - pSW == NULL || pUDSN == NULL || pSLM == NULL ) - { - FreeLibrary(m_hDbhHelp); - m_hDbhHelp = NULL; - pSC = NULL; - return FALSE; - } - - // SymInitialize - if (szSymPath != NULL) - m_szSymPath = _strdup(szSymPath); - if (this->pSI(m_hProcess, m_szSymPath, FALSE) == FALSE) - this->m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0); - - DWORD symOptions = this->pSGO(); // SymGetOptions - symOptions |= SYMOPT_LOAD_LINES; - symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS; - //symOptions |= SYMOPT_NO_PROMPTS; - // SymSetOptions - symOptions = this->pSSO(symOptions); - - char buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0}; - if (this->pSGSP != NULL) - { - if (this->pSGSP(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE) - this->m_parent->OnDbgHelpErr("SymGetSearchPath", GetLastError(), 0); - } - char szUserName[1024] = {0}; - DWORD dwSize = 1024; - GetUserNameA(szUserName, &dwSize); - this->m_parent->OnSymInit(buf, symOptions, szUserName); - - return TRUE; - } - - StackWalker *m_parent; - - HMODULE m_hDbhHelp; - HANDLE m_hProcess; - LPSTR m_szSymPath; - -#pragma pack(push,8) -/*typedef*/ struct IMAGEHLP_MODULE64_V3 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - CHAR ModuleName[32]; // module name - CHAR ImageName[256]; // image name - CHAR LoadedImageName[256]; // symbol file name - // new elements: 07-Jun-2002 - CHAR LoadedPdbName[256]; // pdb file name - DWORD CVSig; // Signature of the CV record in the debug directories - CHAR CVData[MAX_PATH * 3]; // Contents of the CV record - DWORD PdbSig; // Signature of PDB - GUID PdbSig70; // Signature of PDB (VC 7 and up) - DWORD PdbAge; // DBI age of pdb - BOOL PdbUnmatched; // loaded an unmatched pdb - BOOL DbgUnmatched; // loaded an unmatched dbg - BOOL LineNumbers; // we have line number information - BOOL GlobalSymbols; // we have internal symbol information - BOOL TypeInfo; // we have type information - // new elements: 17-Dec-2003 - BOOL SourceIndexed; // pdb supports source server - BOOL Publics; // contains public symbols -}; - -/*typedef*/ struct IMAGEHLP_MODULE64_V2 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - CHAR ModuleName[32]; // module name - CHAR ImageName[256]; // image name - CHAR LoadedImageName[256]; // symbol file name -}; -#pragma pack(pop) - - - // SymCleanup() - typedef BOOL (__stdcall *tSC)( IN HANDLE hProcess ); - tSC pSC; - - // SymFunctionTableAccess64() - typedef PVOID (__stdcall *tSFTA)( HANDLE hProcess, DWORD64 AddrBase ); - tSFTA pSFTA; - - // SymGetLineFromAddr64() - typedef BOOL (__stdcall *tSGLFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, - OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE64 Line ); - tSGLFA pSGLFA; - - // SymGetModuleBase64() - typedef DWORD64 (__stdcall *tSGMB)( IN HANDLE hProcess, IN DWORD64 dwAddr ); - tSGMB pSGMB; - - // SymGetModuleInfo64() - typedef BOOL (__stdcall *tSGMI)( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT IMAGEHLP_MODULE64_V3 *ModuleInfo ); - tSGMI pSGMI; - - // SymGetOptions() - typedef DWORD (__stdcall *tSGO)( VOID ); - tSGO pSGO; - - // SymGetSymFromAddr64() - typedef BOOL (__stdcall *tSGSFA)( IN HANDLE hProcess, IN DWORD64 dwAddr, - OUT PDWORD64 pdwDisplacement, OUT PIMAGEHLP_SYMBOL64 Symbol ); - tSGSFA pSGSFA; - - // SymInitialize() - typedef BOOL (__stdcall *tSI)( IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess ); - tSI pSI; - - // SymLoadModule64() - typedef DWORD64 (__stdcall *tSLM)( IN HANDLE hProcess, IN HANDLE hFile, - IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll ); - tSLM pSLM; - - // SymSetOptions() - typedef DWORD (__stdcall *tSSO)( IN DWORD SymOptions ); - tSSO pSSO; - - // StackWalk64() - typedef BOOL (__stdcall *tSW)( - DWORD MachineType, - HANDLE hProcess, - HANDLE hThread, - LPSTACKFRAME64 StackFrame, - PVOID ContextRecord, - PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, - PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, - PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, - PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress ); - tSW pSW; - - // UnDecorateSymbolName() - typedef DWORD (__stdcall WINAPI *tUDSN)( PCSTR DecoratedName, PSTR UnDecoratedName, - DWORD UndecoratedLength, DWORD Flags ); - tUDSN pUDSN; - - typedef BOOL (__stdcall WINAPI *tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength); - tSGSP pSGSP; - - -private: - // **************************************** ToolHelp32 ************************ - #define MAX_MODULE_NAME32 255 - #define TH32CS_SNAPMODULE 0x00000008 - #pragma pack( push, 8 ) - typedef struct tagMODULEENTRY32 - { - DWORD dwSize; - DWORD th32ModuleID; // This module - DWORD th32ProcessID; // owning process - DWORD GlblcntUsage; // Global usage count on the module - DWORD ProccntUsage; // Module usage count in th32ProcessID's context - BYTE * modBaseAddr; // Base address of module in th32ProcessID's context - DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr - HMODULE hModule; // The hModule of this module in th32ProcessID's context - char szModule[MAX_MODULE_NAME32 + 1]; - char szExePath[MAX_PATH]; - } MODULEENTRY32; - typedef MODULEENTRY32 * PMODULEENTRY32; - typedef MODULEENTRY32 * LPMODULEENTRY32; - #pragma pack( pop ) - - BOOL GetModuleListTH32(HANDLE hProcess, DWORD pid) - { - // CreateToolhelp32Snapshot() - typedef HANDLE (__stdcall *tCT32S)(DWORD dwFlags, DWORD th32ProcessID); - // Module32First() - typedef BOOL (__stdcall *tM32F)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); - // Module32Next() - typedef BOOL (__stdcall *tM32N)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); - - // try both dlls... - const TCHAR *dllname[] = { _T("kernel32.dll"), _T("tlhelp32.dll") }; - HINSTANCE hToolhelp = NULL; - tCT32S pCT32S = NULL; - tM32F pM32F = NULL; - tM32N pM32N = NULL; - - HANDLE hSnap; - MODULEENTRY32 me; - me.dwSize = sizeof(me); - BOOL keepGoing; - size_t i; - - for (i = 0; i<(sizeof(dllname) / sizeof(dllname[0])); i++ ) - { - hToolhelp = LoadLibrary( dllname[i] ); - if (hToolhelp == NULL) - continue; - pCT32S = (tCT32S) GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot"); - pM32F = (tM32F) GetProcAddress(hToolhelp, "Module32First"); - pM32N = (tM32N) GetProcAddress(hToolhelp, "Module32Next"); - if ( (pCT32S != NULL) && (pM32F != NULL) && (pM32N != NULL) ) - break; // found the functions! - FreeLibrary(hToolhelp); - hToolhelp = NULL; - } - - if (hToolhelp == NULL) - return FALSE; - - hSnap = pCT32S( TH32CS_SNAPMODULE, pid ); - if (hSnap == (HANDLE) -1) - { - FreeLibrary(hToolhelp); - return FALSE; - } - - keepGoing = !!pM32F( hSnap, &me ); - int cnt = 0; - while (keepGoing) - { - this->LoadModule(hProcess, me.szExePath, me.szModule, (DWORD64) me.modBaseAddr, me.modBaseSize); - cnt++; - keepGoing = !!pM32N( hSnap, &me ); - } - CloseHandle(hSnap); - FreeLibrary(hToolhelp); - if (cnt <= 0) - return FALSE; - return TRUE; - } // GetModuleListTH32 - - // **************************************** PSAPI ************************ - typedef struct _MODULEINFO { - LPVOID lpBaseOfDll; - DWORD SizeOfImage; - LPVOID EntryPoint; - } MODULEINFO, *LPMODULEINFO; - - BOOL GetModuleListPSAPI(HANDLE hProcess) - { - // EnumProcessModules() - typedef BOOL (__stdcall *tEPM)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ); - // GetModuleFileNameEx() - typedef DWORD (__stdcall *tGMFNE)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); - // GetModuleBaseName() - typedef DWORD (__stdcall *tGMBN)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); - // GetModuleInformation() - typedef BOOL (__stdcall *tGMI)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize ); - - HINSTANCE hPsapi; - tEPM pEPM; - tGMFNE pGMFNE; - tGMBN pGMBN; - tGMI pGMI; - - DWORD i; - //ModuleEntry e; - DWORD cbNeeded; - MODULEINFO mi; - HMODULE *hMods = 0; - char *tt = NULL; - char *tt2 = NULL; - const SIZE_T TTBUFLEN = 8096; - int cnt = 0; - - hPsapi = LoadLibrary( _T("psapi.dll") ); - if (hPsapi == NULL) - return FALSE; - - pEPM = (tEPM) GetProcAddress( hPsapi, "EnumProcessModules" ); - pGMFNE = (tGMFNE) GetProcAddress( hPsapi, "GetModuleFileNameExA" ); - pGMBN = (tGMFNE) GetProcAddress( hPsapi, "GetModuleBaseNameA" ); - pGMI = (tGMI) GetProcAddress( hPsapi, "GetModuleInformation" ); - if ( (pEPM == NULL) || (pGMFNE == NULL) || (pGMBN == NULL) || (pGMI == NULL) ) - { - // we couldnīt find all functions - FreeLibrary(hPsapi); - return FALSE; - } - - hMods = (HMODULE*) malloc(sizeof(HMODULE) * (TTBUFLEN / sizeof(HMODULE))); - tt = (char*) malloc(sizeof(char) * TTBUFLEN); - tt2 = (char*) malloc(sizeof(char) * TTBUFLEN); - if ( (hMods == NULL) || (tt == NULL) || (tt2 == NULL) ) - goto cleanup; - - if ( ! pEPM( hProcess, hMods, TTBUFLEN, &cbNeeded ) ) - { - //_ftprintf(fLogFile, _T("%lu: EPM failed, GetLastError = %lu\n"), g_dwShowCount, gle ); - goto cleanup; - } - - if ( cbNeeded > TTBUFLEN ) - { - //_ftprintf(fLogFile, _T("%lu: More than %lu module handles. Huh?\n"), g_dwShowCount, lenof( hMods ) ); - goto cleanup; - } - - for ( i = 0; i < cbNeeded / sizeof(hMods[0]); i++ ) - { - // base address, size - pGMI(hProcess, hMods[i], &mi, sizeof(mi)); - // image file name - tt[0] = 0; - pGMFNE(hProcess, hMods[i], tt, TTBUFLEN ); - // module name - tt2[0] = 0; - pGMBN(hProcess, hMods[i], tt2, TTBUFLEN ); - - DWORD dwRes = this->LoadModule(hProcess, tt, tt2, (DWORD64) mi.lpBaseOfDll, mi.SizeOfImage); - if (dwRes != ERROR_SUCCESS) - this->m_parent->OnDbgHelpErr("LoadModule", dwRes, 0); - cnt++; - } - - cleanup: - if (hPsapi != NULL) FreeLibrary(hPsapi); - if (tt2 != NULL) free(tt2); - if (tt != NULL) free(tt); - if (hMods != NULL) free(hMods); - - return cnt != 0; - } // GetModuleListPSAPI - - DWORD LoadModule(HANDLE hProcess, LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size) - { - CHAR *szImg = _strdup(img); - CHAR *szMod = _strdup(mod); - DWORD result = ERROR_SUCCESS; - if ( (szImg == NULL) || (szMod == NULL) ) - result = ERROR_NOT_ENOUGH_MEMORY; - else - { - if (pSLM(hProcess, 0, szImg, szMod, baseAddr, size) == 0) - result = GetLastError(); - } - ULONGLONG fileVersion = 0; - if ( (m_parent != NULL) && (szImg != NULL) ) - { - // try to retrive the file-version: - if ( (this->m_parent->m_options & StackWalker::RetrieveFileVersion) != 0) - { - VS_FIXEDFILEINFO *fInfo = NULL; - DWORD dwHandle; - DWORD dwSize = GetFileVersionInfoSizeA(szImg, &dwHandle); - if (dwSize > 0) - { - LPVOID vData = malloc(dwSize); - if (vData != NULL) - { - if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0) - { - UINT len; - TCHAR szSubBlock[] = _T("\\"); - if (VerQueryValue(vData, szSubBlock, (LPVOID*) &fInfo, &len) == 0) - fInfo = NULL; - else - { - fileVersion = ((ULONGLONG)fInfo->dwFileVersionLS) + ((ULONGLONG)fInfo->dwFileVersionMS << 32); - } - } - free(vData); - } - } - } - - // Retrive some additional-infos about the module - IMAGEHLP_MODULE64_V3 Module; - const char *szSymType = "-unknown-"; - if (this->GetModuleInfo(hProcess, baseAddr, &Module) != FALSE) - { - switch(Module.SymType) - { - case SymNone: - szSymType = "-nosymbols-"; - break; - case SymCoff: // 1 - szSymType = "COFF"; - break; - case SymCv: // 2 - szSymType = "CV"; - break; - case SymPdb: // 3 - szSymType = "PDB"; - break; - case SymExport: // 4 - szSymType = "-exported-"; - break; - case SymDeferred: // 5 - szSymType = "-deferred-"; - break; - case SymSym: // 6 - szSymType = "SYM"; - break; - case 7: // SymDia: - szSymType = "DIA"; - break; - case 8: //SymVirtual: - szSymType = "Virtual"; - break; - } - } - LPCSTR pdbName = Module.LoadedImageName; - if (Module.LoadedPdbName[0] != 0) - pdbName = Module.LoadedPdbName; - this->m_parent->OnLoadModule(img, mod, baseAddr, size, result, szSymType, pdbName, fileVersion); - } - if (szImg != NULL) free(szImg); - if (szMod != NULL) free(szMod); - return result; - } -public: - BOOL LoadModules(HANDLE hProcess, DWORD dwProcessId) - { - // first try toolhelp32 - if (GetModuleListTH32(hProcess, dwProcessId)) - return true; - // then try psapi - return GetModuleListPSAPI(hProcess); - } - - - BOOL GetModuleInfo(HANDLE hProcess, DWORD64 baseAddr, IMAGEHLP_MODULE64_V3 *pModuleInfo) - { - memset(pModuleInfo, 0, sizeof(IMAGEHLP_MODULE64_V3)); - if(this->pSGMI == NULL) - { - SetLastError(ERROR_DLL_INIT_FAILED); - return FALSE; - } - // First try to use the larger ModuleInfo-Structure - pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V3); - void *pData = malloc(4096); // reserve enough memory, so the bug in v6.3.5.1 does not lead to memory-overwrites... - if (pData == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V3)); - static bool s_useV3Version = true; - if (s_useV3Version) - { - if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*) pData) != FALSE) - { - // only copy as much memory as is reserved... - memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V3)); - pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V3); - free(pData); - return TRUE; - } - s_useV3Version = false; // to prevent unneccessarry calls with the larger struct... - } - - // could not retrive the bigger structure, try with the smaller one (as defined in VC7.1)... - pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); - memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V2)); - if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*) pData) != FALSE) - { - // only copy as much memory as is reserved... - memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V2)); - pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); - free(pData); - return TRUE; - } - free(pData); - SetLastError(ERROR_DLL_INIT_FAILED); - return FALSE; - } -}; - -// ############################################################# -StackWalker::StackWalker(DWORD dwProcessId, HANDLE hProcess) -{ - this->m_options = OptionsAll; - this->m_modulesLoaded = FALSE; - this->m_hProcess = hProcess; - this->m_sw = new StackWalkerInternal(this, this->m_hProcess); - this->m_dwProcessId = dwProcessId; - this->m_szSymPath = NULL; - this->m_MaxRecursionCount = 1000; -} -StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess) -{ - this->m_options = options; - this->m_modulesLoaded = FALSE; - this->m_hProcess = hProcess; - this->m_sw = new StackWalkerInternal(this, this->m_hProcess); - this->m_dwProcessId = dwProcessId; - if (szSymPath != NULL) - { - this->m_szSymPath = _strdup(szSymPath); - this->m_options |= SymBuildPath; - } - else - this->m_szSymPath = NULL; - this->m_MaxRecursionCount = 1000; -} - -StackWalker::~StackWalker() -{ - if (m_szSymPath != NULL) - free(m_szSymPath); - m_szSymPath = NULL; - if (this->m_sw != NULL) - delete this->m_sw; - this->m_sw = NULL; -} - -BOOL StackWalker::LoadModules() -{ - if (this->m_sw == NULL) - { - SetLastError(ERROR_DLL_INIT_FAILED); - return FALSE; - } - if (m_modulesLoaded != FALSE) - return TRUE; - - // Build the sym-path: - char *szSymPath = NULL; - if ( (this->m_options & SymBuildPath) != 0) - { - const size_t nSymPathLen = 4096; - szSymPath = (char*) malloc(nSymPathLen); - if (szSymPath == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - szSymPath[0] = 0; - // Now first add the (optional) provided sympath: - if (this->m_szSymPath != NULL) - { - strcat_s(szSymPath, nSymPathLen, this->m_szSymPath); - strcat_s(szSymPath, nSymPathLen, ";"); - } - - strcat_s(szSymPath, nSymPathLen, ".;"); - - const size_t nTempLen = 1024; - char szTemp[nTempLen]; - // Now add the current directory: - if (GetCurrentDirectoryA(nTempLen, szTemp) > 0) - { - szTemp[nTempLen-1] = 0; - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - } - - // Now add the path for the main-module: - if (GetModuleFileNameA(NULL, szTemp, nTempLen) > 0) - { - szTemp[nTempLen-1] = 0; - for (char *p = (szTemp+strlen(szTemp)-1); p >= szTemp; --p) - { - // locate the rightmost path separator - if ( (*p == '\\') || (*p == '/') || (*p == ':') ) - { - *p = 0; - break; - } - } // for (search for path separator...) - if (strlen(szTemp) > 0) - { - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - } - } - if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0) - { - szTemp[nTempLen-1] = 0; - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - } - if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0) - { - szTemp[nTempLen-1] = 0; - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - } - if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0) - { - szTemp[nTempLen-1] = 0; - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - // also add the "system32"-directory: - strcat_s(szTemp, nTempLen, "\\system32"); - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, ";"); - } - - if ( (this->m_options & SymUseSymSrv) != 0) - { - if (GetEnvironmentVariableA("SYSTEMDRIVE", szTemp, nTempLen) > 0) - { - szTemp[nTempLen-1] = 0; - strcat_s(szSymPath, nSymPathLen, "SRV*"); - strcat_s(szSymPath, nSymPathLen, szTemp); - strcat_s(szSymPath, nSymPathLen, "\\websymbols"); - strcat_s(szSymPath, nSymPathLen, "*http://msdl.microsoft.com/download/symbols;"); - } - else - strcat_s(szSymPath, nSymPathLen, "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;"); - } - } // if SymBuildPath - - // First Init the whole stuff... - BOOL bRet = this->m_sw->Init(szSymPath); - if (szSymPath != NULL) free(szSymPath); szSymPath = NULL; - if (bRet == FALSE) - { - this->OnDbgHelpErr("Error while initializing dbghelp.dll", 0, 0); - SetLastError(ERROR_DLL_INIT_FAILED); - return FALSE; - } - - bRet = this->m_sw->LoadModules(this->m_hProcess, this->m_dwProcessId); - if (bRet != FALSE) - m_modulesLoaded = TRUE; - return bRet; -} - - -// The following is used to pass the "userData"-Pointer to the user-provided readMemoryFunction -// This has to be done due to a problem with the "hProcess"-parameter in x64... -// Because this class is in no case multi-threading-enabled (because of the limitations -// of dbghelp.dll) it is "safe" to use a static-variable -static StackWalker::PReadProcessMemoryRoutine s_readMemoryFunction = NULL; -static LPVOID s_readMemoryFunction_UserData = NULL; - -BOOL StackWalker::ShowCallstack(HANDLE hThread, const CONTEXT *context, PReadProcessMemoryRoutine readMemoryFunction, LPVOID pUserData) -{ - CONTEXT c; - CallstackEntry csEntry; - IMAGEHLP_SYMBOL64 *pSym = NULL; - StackWalkerInternal::IMAGEHLP_MODULE64_V3 Module; - IMAGEHLP_LINE64 Line; - int frameNum; - bool bLastEntryCalled = true; - int curRecursionCount = 0; - - if (m_modulesLoaded == FALSE) - this->LoadModules(); // ignore the result... - - if (this->m_sw->m_hDbhHelp == NULL) - { - SetLastError(ERROR_DLL_INIT_FAILED); - return FALSE; - } - - s_readMemoryFunction = readMemoryFunction; - s_readMemoryFunction_UserData = pUserData; - - if (context == NULL) - { - // If no context is provided, capture the context - // See: https://stackwalker.codeplex.com/discussions/446958 -#if _WIN32_WINNT <= 0x0501 - // If we need to support XP, we need to use the "old way", because "GetThreadId" is not available! - if (hThread == GetCurrentThread()) -#else - if (GetThreadId(hThread) == GetCurrentThreadId()) -#endif - { - GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, USED_CONTEXT_FLAGS); - } - else - { - SuspendThread(hThread); - memset(&c, 0, sizeof(CONTEXT)); - c.ContextFlags = USED_CONTEXT_FLAGS; - if (GetThreadContext(hThread, &c) == FALSE) - { - ResumeThread(hThread); - return FALSE; - } - } - } - else - c = *context; - - // init STACKFRAME for first call - STACKFRAME64 s; // in/out stackframe - memset(&s, 0, sizeof(s)); - DWORD imageType; -#ifdef _M_IX86 - // normally, call ImageNtHeader() and use machine info from PE header - imageType = IMAGE_FILE_MACHINE_I386; - s.AddrPC.Offset = c.Eip; - s.AddrPC.Mode = AddrModeFlat; - s.AddrFrame.Offset = c.Ebp; - s.AddrFrame.Mode = AddrModeFlat; - s.AddrStack.Offset = c.Esp; - s.AddrStack.Mode = AddrModeFlat; -#elif _M_X64 - imageType = IMAGE_FILE_MACHINE_AMD64; - s.AddrPC.Offset = c.Rip; - s.AddrPC.Mode = AddrModeFlat; - s.AddrFrame.Offset = c.Rsp; - s.AddrFrame.Mode = AddrModeFlat; - s.AddrStack.Offset = c.Rsp; - s.AddrStack.Mode = AddrModeFlat; -#elif _M_IA64 - imageType = IMAGE_FILE_MACHINE_IA64; - s.AddrPC.Offset = c.StIIP; - s.AddrPC.Mode = AddrModeFlat; - s.AddrFrame.Offset = c.IntSp; - s.AddrFrame.Mode = AddrModeFlat; - s.AddrBStore.Offset = c.RsBSP; - s.AddrBStore.Mode = AddrModeFlat; - s.AddrStack.Offset = c.IntSp; - s.AddrStack.Mode = AddrModeFlat; -#else -#error "Platform not supported!" -#endif - - pSym = (IMAGEHLP_SYMBOL64 *) malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); - if (!pSym) goto cleanup; // not enough memory... - memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); - pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); - pSym->MaxNameLength = STACKWALK_MAX_NAMELEN; - - memset(&Line, 0, sizeof(Line)); - Line.SizeOfStruct = sizeof(Line); - - memset(&Module, 0, sizeof(Module)); - Module.SizeOfStruct = sizeof(Module); - - for (frameNum = 0; ; ++frameNum ) - { - // get next stack frame (StackWalk64(), SymFunctionTableAccess64(), SymGetModuleBase64()) - // if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can - // assume that either you are done, or that the stack is so hosed that the next - // deeper frame could not be found. - // CONTEXT need not to be suplied if imageTyp is IMAGE_FILE_MACHINE_I386! - if ( ! this->m_sw->pSW(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem, this->m_sw->pSFTA, this->m_sw->pSGMB, NULL) ) - { - // INFO: "StackWalk64" does not set "GetLastError"... - this->OnDbgHelpErr("StackWalk64", 0, s.AddrPC.Offset); - break; - } - - csEntry.offset = s.AddrPC.Offset; - csEntry.name[0] = 0; - csEntry.undName[0] = 0; - csEntry.undFullName[0] = 0; - csEntry.offsetFromSmybol = 0; - csEntry.offsetFromLine = 0; - csEntry.lineFileName[0] = 0; - csEntry.lineNumber = 0; - csEntry.loadedImageName[0] = 0; - csEntry.moduleName[0] = 0; - if (s.AddrPC.Offset == s.AddrReturn.Offset) - { - if ( (this->m_MaxRecursionCount > 0) && (curRecursionCount > m_MaxRecursionCount) ) - { - this->OnDbgHelpErr("StackWalk64-Endless-Callstack!", 0, s.AddrPC.Offset); - break; - } - curRecursionCount++; - } - else - curRecursionCount = 0; - if (s.AddrPC.Offset != 0) - { - // we seem to have a valid PC - // show procedure info (SymGetSymFromAddr64()) - if (this->m_sw->pSGSFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol), pSym) != FALSE) - { - MyStrCpy(csEntry.name, STACKWALK_MAX_NAMELEN, pSym->Name); - // UnDecorateSymbolName() - this->m_sw->pUDSN( pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY ); - this->m_sw->pUDSN( pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE ); - } - else - { - this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), s.AddrPC.Offset); - } - - // show line number info, NT5.0-method (SymGetLineFromAddr64()) - if (this->m_sw->pSGLFA != NULL ) - { // yes, we have SymGetLineFromAddr64() - if (this->m_sw->pSGLFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine), &Line) != FALSE) - { - csEntry.lineNumber = Line.LineNumber; - MyStrCpy(csEntry.lineFileName, STACKWALK_MAX_NAMELEN, Line.FileName); - } - else - { - this->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), s.AddrPC.Offset); - } - } // yes, we have SymGetLineFromAddr64() - - // show module info (SymGetModuleInfo64()) - if (this->m_sw->GetModuleInfo(this->m_hProcess, s.AddrPC.Offset, &Module ) != FALSE) - { // got module info OK - switch ( Module.SymType ) - { - case SymNone: - csEntry.symTypeString = "-nosymbols-"; - break; - case SymCoff: - csEntry.symTypeString = "COFF"; - break; - case SymCv: - csEntry.symTypeString = "CV"; - break; - case SymPdb: - csEntry.symTypeString = "PDB"; - break; - case SymExport: - csEntry.symTypeString = "-exported-"; - break; - case SymDeferred: - csEntry.symTypeString = "-deferred-"; - break; - case SymSym: - csEntry.symTypeString = "SYM"; - break; -#if API_VERSION_NUMBER >= 9 - case SymDia: - csEntry.symTypeString = "DIA"; - break; -#endif - case 8: //SymVirtual: - csEntry.symTypeString = "Virtual"; - break; - default: - //_snprintf( ty, sizeof(ty), "symtype=%ld", (long) Module.SymType ); - csEntry.symTypeString = NULL; - break; - } - - MyStrCpy(csEntry.moduleName, STACKWALK_MAX_NAMELEN, Module.ModuleName); - csEntry.baseOfImage = Module.BaseOfImage; - MyStrCpy(csEntry.loadedImageName, STACKWALK_MAX_NAMELEN, Module.LoadedImageName); - } // got module info OK - else - { - this->OnDbgHelpErr("SymGetModuleInfo64", GetLastError(), s.AddrPC.Offset); - } - } // we seem to have a valid PC - - CallstackEntryType et = nextEntry; - if (frameNum == 0) - et = firstEntry; - bLastEntryCalled = false; - this->OnCallstackEntry(et, csEntry); - - if (s.AddrReturn.Offset == 0) - { - bLastEntryCalled = true; - this->OnCallstackEntry(lastEntry, csEntry); - SetLastError(ERROR_SUCCESS); - break; - } - } // for ( frameNum ) - - cleanup: - if (pSym) free( pSym ); - - if (bLastEntryCalled == false) - this->OnCallstackEntry(lastEntry, csEntry); - - if (context == NULL) - ResumeThread(hThread); - - return TRUE; -} - -BOOL __stdcall StackWalker::myReadProcMem( - HANDLE hProcess, - DWORD64 qwBaseAddress, - PVOID lpBuffer, - DWORD nSize, - LPDWORD lpNumberOfBytesRead - ) -{ - if (s_readMemoryFunction == NULL) - { - SIZE_T st; - BOOL bRet = ReadProcessMemory(hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, &st); - *lpNumberOfBytesRead = (DWORD) st; - //printf("ReadMemory: hProcess: %p, baseAddr: %p, buffer: %p, size: %d, read: %d, result: %d\n", hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, (DWORD) st, (DWORD) bRet); - return bRet; - } - else - { - return s_readMemoryFunction(hProcess, qwBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead, s_readMemoryFunction_UserData); - } -} - -void StackWalker::OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion) -{ - CHAR buffer[STACKWALK_MAX_NAMELEN]; - if (fileVersion == 0) - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName); - else - { - DWORD v4 = (DWORD) (fileVersion & 0xFFFF); - DWORD v3 = (DWORD) ((fileVersion>>16) & 0xFFFF); - DWORD v2 = (DWORD) ((fileVersion>>32) & 0xFFFF); - DWORD v1 = (DWORD) ((fileVersion>>48) & 0xFFFF); - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName, v1, v2, v3, v4); - } - OnOutput(buffer); -} - -void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) -{ - CHAR buffer[STACKWALK_MAX_NAMELEN]; - if ( (eType != lastEntry) && (entry.offset != 0) ) - { - if (entry.name[0] == 0) - MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)"); - if (entry.undName[0] != 0) - MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undName); - if (entry.undFullName[0] != 0) - MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName); - if (entry.lineFileName[0] == 0) - { - MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)"); - if (entry.moduleName[0] == 0) - MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, "(module-name not available)"); - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%p (%s): %s: %s\n", (LPVOID) entry.offset, entry.moduleName, entry.lineFileName, entry.name); - } - else - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s (%d): %s\n", entry.lineFileName, entry.lineNumber, entry.name); - buffer[STACKWALK_MAX_NAMELEN-1] = 0; - OnOutput(buffer); - } -} - -void StackWalker::OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr) -{ - CHAR buffer[STACKWALK_MAX_NAMELEN]; - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "ERROR: %s, GetLastError: %d (Address: %p)\n", szFuncName, gle, (LPVOID) addr); - OnOutput(buffer); -} - -void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName) -{ - CHAR buffer[STACKWALK_MAX_NAMELEN]; - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n", szSearchPath, symOptions, szUserName); - OnOutput(buffer); - // Also display the OS-version -#if _MSC_VER <= 1200 - OSVERSIONINFOA ver; - ZeroMemory(&ver, sizeof(OSVERSIONINFOA)); - ver.dwOSVersionInfoSize = sizeof(ver); - if (GetVersionExA(&ver) != FALSE) - { - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s)\n", - ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, - ver.szCSDVersion); - OnOutput(buffer); - } -#else - -#pragma warning(push) -#pragma warning(disable : 4996) // GetVersionExA was declared deprecated - - OSVERSIONINFOEXA ver; - ZeroMemory(&ver, sizeof(OSVERSIONINFOEXA)); - ver.dwOSVersionInfoSize = sizeof(ver); - if (GetVersionExA( (OSVERSIONINFOA*) &ver) != FALSE) - { - _snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n", - ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, - ver.szCSDVersion, ver.wSuiteMask, ver.wProductType); - OnOutput(buffer); - } - -#pragma warning(pop) - -#endif -} - -void StackWalker::OnOutput(LPCSTR buffer) -{ - OutputDebugStringA(buffer); -} diff --git a/Core/src/BlueFramework/Core/Diagnostics/StackWalker.h b/Core/src/BlueFramework/Core/Diagnostics/StackWalker.h deleted file mode 100644 index 91fe277..0000000 --- a/Core/src/BlueFramework/Core/Diagnostics/StackWalker.h +++ /dev/null @@ -1,220 +0,0 @@ -// Copied and modified code from "StackWalker". -// This code is available under the BSD license. Original copyright notice: - -/********************************************************************** - * - * StackWalker.h - * - * - * - * LICENSE (http://www.opensource.org/licenses/bsd-license.php) - * - * Copyright (c) 2005-2009, Jochen Kalmbach - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of Jochen Kalmbach nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * **********************************************************************/ - - // More details can be found in README.md file in the root directory. - -// #pragma once is supported starting with _MCS_VER 1000, -// so we need not to check the version (because we only support _MSC_VER >= 1100)! -#pragma once - -#include - -// special defines for VC5/6 (if no actual PSDK is installed): -#if _MSC_VER < 1300 -typedef unsigned __int64 DWORD64, *PDWORD64; -#if defined(_WIN64) -typedef unsigned __int64 SIZE_T, *PSIZE_T; -#else -typedef unsigned long SIZE_T, *PSIZE_T; -#endif -#endif // _MSC_VER < 1300 - -class StackWalkerInternal; // forward -class StackWalker -{ -public: - typedef enum StackWalkOptions - { - // No addition info will be retrived - // (only the address is available) - RetrieveNone = 0, - - // Try to get the symbol-name - RetrieveSymbol = 1, - - // Try to get the line for this symbol - RetrieveLine = 2, - - // Try to retrieve the module-infos - RetrieveModuleInfo = 4, - - // Also retrieve the version for the DLL/EXE - RetrieveFileVersion = 8, - - // Contains all the abouve - RetrieveVerbose = 0xF, - - // Generate a "good" symbol-search-path - SymBuildPath = 0x10, - - // Also use the public Microsoft-Symbol-Server - SymUseSymSrv = 0x20, - - // Contains all the abouve "Sym"-options - SymAll = 0x30, - - // Contains all options (default) - OptionsAll = 0x3F - } StackWalkOptions; - - StackWalker( - int options = OptionsAll, // 'int' is by design, to combine the enum-flags - LPCSTR szSymPath = NULL, - DWORD dwProcessId = GetCurrentProcessId(), - HANDLE hProcess = GetCurrentProcess() - ); - StackWalker(DWORD dwProcessId, HANDLE hProcess); - virtual ~StackWalker(); - - typedef BOOL (__stdcall *PReadProcessMemoryRoutine)( - HANDLE hProcess, - DWORD64 qwBaseAddress, - PVOID lpBuffer, - DWORD nSize, - LPDWORD lpNumberOfBytesRead, - LPVOID pUserData // optional data, which was passed in "ShowCallstack" - ); - - BOOL LoadModules(); - - BOOL ShowCallstack( - HANDLE hThread = GetCurrentThread(), - const CONTEXT *context = NULL, - PReadProcessMemoryRoutine readMemoryFunction = NULL, - LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback - ); - -#if _MSC_VER >= 1300 -// due to some reasons, the "STACKWALK_MAX_NAMELEN" must be declared as "public" -// in older compilers in order to use it... starting with VC7 we can declare it as "protected" -protected: -#endif - enum { STACKWALK_MAX_NAMELEN = 1024 }; // max name length for found symbols - -protected: - // Entry for each Callstack-Entry - typedef struct CallstackEntry - { - DWORD64 offset; // if 0, we have no valid entry - CHAR name[STACKWALK_MAX_NAMELEN]; - CHAR undName[STACKWALK_MAX_NAMELEN]; - CHAR undFullName[STACKWALK_MAX_NAMELEN]; - DWORD64 offsetFromSmybol; - DWORD offsetFromLine; - DWORD lineNumber; - CHAR lineFileName[STACKWALK_MAX_NAMELEN]; - DWORD symType; - LPCSTR symTypeString; - CHAR moduleName[STACKWALK_MAX_NAMELEN]; - DWORD64 baseOfImage; - CHAR loadedImageName[STACKWALK_MAX_NAMELEN]; - } CallstackEntry; - - /*typedef*/ enum CallstackEntryType {firstEntry, nextEntry, lastEntry}; - - virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName); - virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion); - virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry); - virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr); - virtual void OnOutput(LPCSTR szText); - - StackWalkerInternal *m_sw; - HANDLE m_hProcess; - DWORD m_dwProcessId; - BOOL m_modulesLoaded; - LPSTR m_szSymPath; - - int m_options; - int m_MaxRecursionCount; - - static BOOL __stdcall myReadProcMem(HANDLE hProcess, DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead); - - friend StackWalkerInternal; -}; // class StackWalker - - -// The "ugly" assembler-implementation is needed for systems before XP -// If you have a new PSDK and you only compile for XP and later, then you can use -// the "RtlCaptureContext" -// Currently there is no define which determines the PSDK-Version... -// So we just use the compiler-version (and assumes that the PSDK is -// the one which was installed by the VS-IDE) - -// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later... -// But I currently use it in x64/IA64 environments... -//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400) - -#if defined(_M_IX86) -#ifdef CURRENT_THREAD_VIA_EXCEPTION -// TODO: The following is not a "good" implementation, -// because the callstack is only valid in the "__except" block... -#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \ - do { \ - memset(&c, 0, sizeof(CONTEXT)); \ - EXCEPTION_POINTERS *pExp = NULL; \ - __try { \ - throw 0; \ - } __except( ( (pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_EXECUTE_HANDLER)) {} \ - if (pExp != NULL) \ - memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT)); \ - c.ContextFlags = contextFlags; \ - } while(0); -#else -// The following should be enough for walking the callstack... -#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \ - do { \ - memset(&c, 0, sizeof(CONTEXT)); \ - c.ContextFlags = contextFlags; \ - __asm call x \ - __asm x: pop eax \ - __asm mov c.Eip, eax \ - __asm mov c.Ebp, ebp \ - __asm mov c.Esp, esp \ - } while(0); -#endif - -#else - -// The following is defined for x86 (XP and higher), x64 and IA64: -#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \ - do { \ - memset(&c, 0, sizeof(CONTEXT)); \ - c.ContextFlags = contextFlags; \ - RtlCaptureContext(&c); \ -} while(0); -#endif diff --git a/Core/src/BlueFramework/Core/Diagnostics/ic/ic.cpp b/Core/src/BlueFramework/Core/Diagnostics/ic/ic.cpp index 444298a..87c927d 100644 --- a/Core/src/BlueFramework/Core/Diagnostics/ic/ic.cpp +++ b/Core/src/BlueFramework/Core/Diagnostics/ic/ic.cpp @@ -10,8 +10,18 @@ #include "ic.hpp" +#include +#include + +#if _MSVC_LANG < 202000L +#include +#endif + namespace ic { + using convert_type = std::codecvt_utf8; + auto converter = std::wstring_convert(); + const COORD Console::origin = {0, 0}; Console::Console () @@ -236,8 +246,8 @@ namespace ic void Console::setWindowSize (int width, int height) { // Make sure the screen buffer is at least as large as the window - int newBufferWidth = max(width, getBufferWidth()); - int newBufferHeight = max(height, getBufferHeight()); + int newBufferWidth = std::max(width, getBufferWidth()); + int newBufferHeight = std::max(height, getBufferHeight()); setBufferSizeNoModeCheck(newBufferWidth, newBufferHeight); SMALL_RECT rect; @@ -281,8 +291,8 @@ namespace ic // Make sure to stay within the bounds of the screen buffer SMALL_RECT rect; - rect.Bottom = static_cast(min(y + height, getBufferHeight()) - 1); - rect.Right = static_cast(min(x + width, getBufferWidth()) - 1); + rect.Bottom = static_cast(std::min(y + height, getBufferHeight()) - 1); + rect.Right = static_cast(std::min(x + width, getBufferWidth()) - 1); rect.Left = static_cast(rect.Right - width + 1); rect.Top = static_cast(rect.Bottom - height + 1); SetConsoleWindowInfo(hConsoleOutput, TRUE, &rect); @@ -312,14 +322,22 @@ namespace ic const int MAX_TITLE_LEN = 64 * 1024; // 64K, see MSDN WCHAR title [MAX_TITLE_LEN]; +#ifdef UNICODE GetConsoleTitle(title, MAX_TITLE_LEN); +#else + GetConsoleTitle(converter.to_bytes(title).data(), MAX_TITLE_LEN); +#endif return title; } void Console::setTitle (const std::wstring& title) { +#ifdef UNICODE SetConsoleTitle(title.c_str()); +#else + SetConsoleTitle(converter.to_bytes(title).c_str()); +#endif } CONSOLE_CURSOR_INFO Console::getCCI () const diff --git a/Core/src/BlueFramework/Core/Exception.h b/Core/src/BlueFramework/Core/Exception.h index a2a347d..edc4c33 100644 --- a/Core/src/BlueFramework/Core/Exception.h +++ b/Core/src/BlueFramework/Core/Exception.h @@ -26,15 +26,10 @@ #define NOMINMAX #endif -#include "BlueFramework/Core/Diagnostics/StackWalker.h" #include "BlueFramework/Core/assert.h" -#pragma warning(push) -#pragma warning(disable : 4702) -#pragma warning(disable : 4127) -#include "BlueFramework/Core/tinyformat.h" -#pragma warning(pop) - +#include +#include #include BLUEFRAMEWORK_CORE_NAMESPACE_BEGIN diff --git a/Core/src/BlueFramework/Core/Math/util.h b/Core/src/BlueFramework/Core/Math/util.h index 28f9121..3af00b8 100644 --- a/Core/src/BlueFramework/Core/Math/util.h +++ b/Core/src/BlueFramework/Core/Math/util.h @@ -15,13 +15,15 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - -#include "BlueFramework/Core/namespace.h" - #pragma once #ifndef BlueFramework_Core_Math_util_6b3f6d1c_d23a_4641_b619_b13fbd3aa260_h #define BlueFramework_Core_Math_util_6b3f6d1c_d23a_4641_b619_b13fbd3aa260_h +#include "BlueFramework/Core/namespace.h" + +#include +#include + BLUEFRAMEWORK_CORE_MATH_NAMESPACE_BEGIN typedef float radianf; @@ -44,10 +46,6 @@ inline bool isInfinite(const T value) { return std::numeric_limits::has_infinity && (value == std::numeric_limits::infinity()); } -// bool isPower2(int x) -//{ -// return ((x > 0) && ((x & (x - 1)) == 0)); -//} template T log2(const T value) { @@ -121,70 +119,16 @@ T radianToDegree(T i_Rad) { return i_Rad * static_cast(57.295779513082320876798154814105); } -//! Clamps a value to a certain range -/*! -\param value value that should be clamped. -\param lowerBound lower bound of range. -\parma upperBound upper bound of range. -\return clamp value in the range [lowerBound;upperBound] -*/ -template -inline T clamp(const T value, const T lowerBound, const T upperBound) { - if (value <= lowerBound) - return lowerBound; - else if (value >= upperBound) - return upperBound; - else - return value; -} - -#ifdef min -#undef min -#endif // min - -#ifdef max -#undef max -#endif // max - -template -inline T min(const T x, const T y) { - if (x < y) - return x; - else - return y; -} - -template -inline T min(const T x, const T y, const T z) { - return min(min(x, y), z); -} - -template -inline T max(const T x, const T y) { - if (x < y) - return y; - else - return x; -} - -template -inline T max(const T x, const T y, const T z) { - return max(max(x, y), z); -} - -template -inline T ceil(T t) { - return std::ceil(t); -} -template -inline T floor(T t) { - return std::floor(t); -} double round(const double val, const int precision); double factorial(const int n); +// see https://stackoverflow.com/questions/17333/what-is-the-most-effective-way-for-float-and-double-comparison +inline bool doubleEqual(const double a, const double b, const double epsilon = DBL_EPSILON) { + return fabs(a - b) <= ((fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon); +} + BLUEFRAMEWORK_CORE_MATH_NAMESPACE_END BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(radianf) @@ -200,12 +144,8 @@ BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(smoothstep) BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(mod) BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(degreeToRadian) BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(radianToDegree) -BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(clamp) -BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(min) -BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(max) -BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(ceil) -BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(floor) BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(round) BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(factorial) +BLUEFRAMEWORK_CORE_MATH_EMBED_INTO_BUW_NAMESPACE(doubleEqual) #endif // end define BlueFramework_Core_Math_util_6b3f6d1c_d23a_4641_b619_b13fbd3aa260_h diff --git a/Core/src/BlueFramework/Core/PropertySet.cpp b/Core/src/BlueFramework/Core/PropertySet.cpp index ceab3ac..08c45b7 100644 --- a/Core/src/BlueFramework/Core/PropertySet.cpp +++ b/Core/src/BlueFramework/Core/PropertySet.cpp @@ -142,6 +142,8 @@ struct determine_type : public boost::static_visitor { buw::ePropertyType operator()(const buw::Vector4d& /*value*/) const { return ePropertyType::Vector4d; } + + determine_type() = default; }; ePropertyType PropertySet::getPropertyType(const std::string& name) const { diff --git a/Core/src/BlueFramework/Core/Uri.cpp b/Core/src/BlueFramework/Core/Uri.cpp index 2d39e0e..030cb1f 100644 --- a/Core/src/BlueFramework/Core/Uri.cpp +++ b/Core/src/BlueFramework/Core/Uri.cpp @@ -40,13 +40,13 @@ void Uri::parse(const std::string& url_s) { const string prot_end("://"); string::const_iterator prot_i = search(url_s.begin(), url_s.end(), prot_end.begin(), prot_end.end()); protocol_.reserve(distance(url_s.begin(), prot_i)); - transform(url_s.begin(), prot_i, back_inserter(protocol_), ptr_fun(tolower)); // protocol is icase + transform(url_s.begin(), prot_i, back_inserter(protocol_), tolower); // protocol is icase if (prot_i == url_s.end()) return; advance(prot_i, prot_end.length()); string::const_iterator path_i = find(prot_i, url_s.end(), '/'); host_.reserve(distance(prot_i, path_i)); - transform(prot_i, path_i, back_inserter(host_), ptr_fun(tolower)); // host is icase + transform(prot_i, path_i, back_inserter(host_), tolower); // host is icase string::const_iterator query_i = find(path_i, url_s.end(), '?'); path_.assign(path_i, query_i); if (query_i != url_s.end()) diff --git a/Core/src/BlueFramework/Core/tinyformat.h b/Core/src/BlueFramework/Core/tinyformat.h deleted file mode 100644 index d40c43b..0000000 --- a/Core/src/BlueFramework/Core/tinyformat.h +++ /dev/null @@ -1,746 +0,0 @@ -// tinyformat.h -// Copyright (C) 2011, Chris Foster [chris42f (at) gmail (d0t) com] -// -// Boost Software License - Version 1.0 -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -//------------------------------------------------------------------------------ -// Tinyformat: A minimal type safe printf replacement -// -// tinyformat.h is a type safe printf replacement library in a single C++ -// header file. Design goals include: -// -// * Type safety and extensibility for user defined types. -// * C99 printf() compatibility, to the extent possible using std::ostream -// * Simplicity and minimalism. A single header file to include and distribute -// with your projects. -// * Augment rather than replace the standard stream formatting mechanism -// * C++98 support, with optional C++11 niceties -// -// -// Main interface example usage -// ---------------------------- -// -// To print a date to std::cout: -// -// std::string weekday = "Wednesday"; -// const char* month = "July"; -// size_t day = 27; -// long hour = 14; -// int min = 44; -// -// tfm::printf("%s, %s %d, %.2d:%.2d\n", weekday, month, day, hour, min); -// -// The strange types here emphasize the type safety of the interface; it is -// possible to print a std::string using the "%s" conversion, and a -// size_t using the "%d" conversion. A similar result could be achieved -// using either of the tfm::format() functions. One prints on a user provided -// stream: -// -// tfm::format(std::cerr, "%s, %s %d, %.2d:%.2d\n", -// weekday, month, day, hour, min); -// -// The other returns a std::string: -// -// std::string date = tfm::format("%s, %s %d, %.2d:%.2d\n", -// weekday, month, day, hour, min); -// std::cout << date; -// -// These are the three primary interface functions. There is also a -// convenience function printfln() which appends a newline to the usual result -// of printf() for super simple logging. -// -// -// User defined format functions -// ----------------------------- -// -// Simulating variadic templates in C++98 is pretty painful since it requires -// writing out the same function for each desired number of arguments. To make -// this bearable tinyformat comes with a set of macros which are used -// internally to generate the API, but which may also be used in user code. -// -// The three macros TINYFORMAT_ARGTYPES(n), TINYFORMAT_VARARGS(n) and -// TINYFORMAT_PASSARGS(n) will generate a list of n argument types, -// type/name pairs and argument names respectively when called with an integer -// n between 1 and 16. We can use these to define a macro which generates the -// desired user defined function with n arguments. To generate all 16 user -// defined function bodies, use the macro TINYFORMAT_FOREACH_ARGNUM. For an -// example, see the implementation of printf() at the end of the source file. -// -// Sometimes it's useful to be able to pass a list of format arguments through -// to a non-template function. The FormatList class is provided as a way to do -// this by storing the argument list in a type-opaque way. Continuing the -// example from above, we construct a FormatList using makeFormatList(): -// -// FormatListRef formatList = tfm::makeFormatList(weekday, month, day, hour, min); -// -// The format list can now be passed into any non-template function and used -// via a call to the vformat() function: -// -// tfm::vformat(std::cout, "%s, %s %d, %.2d:%.2d\n", formatList); -// -// -// Additional API information -// -------------------------- -// -// Error handling: Define TINYFORMAT_ERROR to customize the error handling for -// format strings which are unsupported or have the wrong number of format -// specifiers (calls assert() by default). -// -// User defined types: Uses operator<< for user defined types by default. -// Overload formatValue() for more control. - -#pragma once -#ifndef TINYFORMAT_H_INCLUDED -#define TINYFORMAT_H_INCLUDED - -namespace tinyformat {} -//------------------------------------------------------------------------------ -// Config section. Customize to your liking! - -// Namespace alias to encourage brevity -namespace tfm = tinyformat; - -// Error handling; calls assert() by default. -#define TINYFORMAT_ERROR(reasonString) throw std::runtime_error(reasonString) - -// Define for C++11 variadic templates which make the code shorter & more -// general. If you don't define this, C++11 support is autodetected below. -#define TINYFORMAT_USE_VARIADIC_TEMPLATES - -//------------------------------------------------------------------------------ -// Implementation details. -#include -#include -#include -#include -#include - -#ifndef TINYFORMAT_ERROR -#define TINYFORMAT_ERROR(reason) assert(0 && reason) -#endif - -#if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201 -// std::showpos is broken on old libstdc++ as provided with OSX. See -// http://gcc.gnu.org/ml/libstdc++/2007-11/msg00075.html -#define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND -#endif - -namespace tinyformat { - - //------------------------------------------------------------------------------ - namespace detail { - - // Test whether type T1 is convertible to type T2 - template - struct is_convertible { - private: - // two types of different size - struct fail { - char dummy[2]; - }; - struct succeed { - char dummy; - }; - // Try to convert a T1 to a T2 by plugging into tryConvert - static fail tryConvert(...); - static succeed tryConvert(const T2&); - static const T1& makeT1(); - - public: -#ifdef _MSC_VER -// Disable spurious loss of precision warnings in tryConvert(makeT1()) -#pragma warning(push) -#pragma warning(disable : 4244) -#pragma warning(disable : 4267) -#endif - // Standard trick: the (...) version of tryConvert will be chosen from - // the overload set only if the version taking a T2 doesn't match. - // Then we compare the sizes of the return types to check which - // function matched. Very neat, in a disgusting kind of way :) - static const bool value = sizeof(tryConvert(makeT1())) == sizeof(succeed); -#ifdef _MSC_VER -#pragma warning(pop) -#endif - }; - - // Detect when a type is not a wchar_t string - template - struct is_wchar { - typedef int tinyformat_wchar_is_not_supported; - }; - template <> - struct is_wchar {}; - template <> - struct is_wchar {}; - template - struct is_wchar {}; - template - struct is_wchar {}; - - // Format the value by casting to type fmtT. This default implementation - // should never be called. - template ::value> - struct formatValueAsType { - static void invoke(std::ostream& /*out*/, const T& /*value*/) { - assert(0); - } - }; - // Specialized version for types that can actually be converted to fmtT, as - // indicated by the "convertible" template parameter. - template - struct formatValueAsType { - static void invoke(std::ostream& out, const T& value) { - out << static_cast(value); - } - }; - -#ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND - template ::value> - struct formatZeroIntegerWorkaround { - static bool invoke(std::ostream& /**/, const T& /**/) { - return false; - } - }; - template - struct formatZeroIntegerWorkaround { - static bool invoke(std::ostream& out, const T& value) { - if (static_cast(value) == 0 && out.flags() & std::ios::showpos) { - out << "+0"; - return true; - } - return false; - } - }; -#endif // TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND - - // Convert an arbitrary type to integer. The version with convertible=false - // throws an error. - template ::value> - struct convertToInt { - static int invoke(const T& /*value*/) { - TINYFORMAT_ERROR( - "tinyformat: Cannot convert from argument type to " - "integer for use as variable width or precision"); - return 0; - } - }; - // Specialization for convertToInt when conversion is possible - template - struct convertToInt { - static int invoke(const T& value) { - return static_cast(value); - } - }; - - // Format at most ntrunc characters to the given stream. - template - inline void formatTruncated(std::ostream& out, const T& value, int ntrunc) { - std::ostringstream tmp; - tmp << value; - std::string result = tmp.str(); - out.write(result.c_str(), std::min(ntrunc, static_cast(result.size()))); - } -#define TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR(type) \ - \ -inline void \ - formatTruncated(std::ostream& out, type* value, int ntrunc) \ -{ \ - std::streamsize len = 0; \ - while (len < ntrunc && value[len] != 0) \ - ++len; \ - out.write(value, len); \ - \ -} - // Overload for const char* and char*. Could overload for signed & unsigned - // char too, but these are technically unneeded for printf compatibility. - TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR(const char) - TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR(char) -#undef TINYFORMAT_DEFINE_FORMAT_TRUNCATED_CSTR - - } // namespace detail - - //------------------------------------------------------------------------------ - // Variable formatting functions. May be overridden for user-defined types if - // desired. - - /// Format a value into a stream, delegating to operator<< by default. - /// - /// Users may override this for their own types. When this function is called, - /// the stream flags will have been modified according to the format string. - /// The format specification is provided in the range [fmtBegin, fmtEnd). For - /// truncating conversions, ntrunc is set to the desired maximum number of - /// characters, for example "%.7s" calls formatValue with ntrunc = 7. - /// - /// By default, formatValue() uses the usual stream insertion operator - /// operator<< to format the type T, with special cases for the %c and %p - /// conversions. - template - inline void formatValue(std::ostream& out, const char* /*fmtBegin*/, const char* fmtEnd, int ntrunc, const T& value) { -#ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS - // Since we don't support printing of wchar_t using "%ls", make it fail at - // compile time in preference to printing as a void* at runtime. - typedef typename detail::is_wchar::tinyformat_wchar_is_not_supported DummyType; - (void)DummyType(); // avoid unused type warning with gcc-4.8 -#endif - // The mess here is to support the %c and %p conversions: if these - // conversions are active we try to convert the type to a char or const - // void* respectively and format that instead of the value itself. For the - // %p conversion it's important to avoid dereferencing the pointer, which - // could otherwise lead to a crash when printing a dangling (const char*). - const bool canConvertToChar = detail::is_convertible::value; - const bool canConvertToVoidPtr = detail::is_convertible::value; - if (canConvertToChar && *(fmtEnd - 1) == 'c') - detail::formatValueAsType::invoke(out, value); - else if (canConvertToVoidPtr && *(fmtEnd - 1) == 'p') - detail::formatValueAsType::invoke(out, value); -#ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND - else if (detail::formatZeroIntegerWorkaround::invoke(out, value)) /**/ - ; -#endif - else if (ntrunc >= 0) { - // Take care not to overread C strings in truncating conversions like - // "%.4s" where at most 4 characters may be read. - detail::formatTruncated(out, value, ntrunc); - } else - out << value; - } - -// Overloaded version for char types to support printing as an integer -#define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType) \ - \ -inline void \ - formatValue(std::ostream& out, const char* /*fmtBegin*/, const char* fmtEnd, int /**/, charType value) \ -{ \ - switch (*(fmtEnd - 1)) { \ - case 'u': \ - case 'd': \ - case 'i': \ - case 'o': \ - case 'X': \ - case 'x': out << static_cast(value); break; \ - default: out << value; break; \ - } \ - \ -} - // per 3.9.1: char, signed char and unsigned char are all distinct types - TINYFORMAT_DEFINE_FORMATVALUE_CHAR(char) - TINYFORMAT_DEFINE_FORMATVALUE_CHAR(signed char) - TINYFORMAT_DEFINE_FORMATVALUE_CHAR(unsigned char) -#undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR - - namespace detail { - - // Type-opaque holder for an argument to format(), with associated actions on - // the type held as explicit function pointers. This allows FormatArg's for - // each argument to be allocated as a homogenous array inside FormatList - // whereas a naive implementation based on inheritance does not. - class FormatArg { - public: - FormatArg() { - } - - template - FormatArg(const T& value) : m_value(static_cast(&value)), m_formatImpl(&formatImpl), m_toIntImpl(&toIntImpl) { - } - - void format(std::ostream& out, const char* fmtBegin, const char* fmtEnd, int ntrunc) const { - m_formatImpl(out, fmtBegin, fmtEnd, ntrunc, m_value); - } - - int toInt() const { - return m_toIntImpl(m_value); - } - - private: - template - static void formatImpl(std::ostream& out, const char* fmtBegin, const char* fmtEnd, int ntrunc, const void* value) { - formatValue(out, fmtBegin, fmtEnd, ntrunc, *static_cast(value)); - } - - template - static int toIntImpl(const void* value) { - return convertToInt::invoke(*static_cast(value)); - } - - const void* m_value; - void (*m_formatImpl)(std::ostream& out, const char* fmtBegin, const char* fmtEnd, int ntrunc, const void* value); - int (*m_toIntImpl)(const void* value); - }; - - // Parse and return an integer from the string c, as atoi() - // On return, c is set to one past the end of the integer. - inline int parseIntAndAdvance(const char*& c) { - int i = 0; - for (; *c >= '0' && *c <= '9'; ++c) - i = 10 * i + (*c - '0'); - return i; - } - - // Print literal part of format string and return next format spec - // position. - // - // Skips over any occurrences of '%%', printing a literal '%' to the - // output. The position of the first % character of the next - // nontrivial format spec is returned, or the end of string. - inline const char* printFormatStringLiteral(std::ostream& out, const char* fmt) { - const char* c = fmt; - for (; true; ++c) { - switch (*c) { - case '\0': out.write(fmt, static_cast(c - fmt)); return c; - case '%': - out.write(fmt, static_cast(c - fmt)); - if (*(c + 1) != '%') - return c; - // for "%%", tack trailing % onto next literal section. - fmt = ++c; - break; - } - } - } - - // Parse a format string and set the stream state accordingly. - // - // The format mini-language recognized here is meant to be the one from C99, - // with the form "%[flags][width][.precision][length]type". - // - // Formatting options which can't be natively represented using the ostream - // state are returned in spacePadPositive (for space padded positive numbers) - // and ntrunc (for truncating conversions). argIndex is incremented if - // necessary to pull out variable width and precision . The function returns a - // pointer to the character after the end of the current format spec. - inline const char* - streamStateFromFormat(std::ostream& out, bool& spacePadPositive, int& ntrunc, const char* fmtStart, const detail::FormatArg* formatters, int& argIndex, int numFormatters) { - if (*fmtStart != '%') { - TINYFORMAT_ERROR("tinyformat: Not enough conversion specifiers in format string"); - return fmtStart; - } - // Reset stream state to defaults. - out.width(0); - out.precision(6); - out.fill(' '); - // Reset most flags; ignore irrelevant unitbuf & skipws. - out.unsetf(std::ios::adjustfield | std::ios::basefield | std::ios::floatfield | std::ios::showbase | std::ios::boolalpha | std::ios::showpoint | std::ios::showpos - | std::ios::uppercase); - bool precisionSet = false; - bool widthSet = false; - int widthExtra = 0; - const char* c = fmtStart + 1; - // 1) Parse flags - for (;; ++c) { - switch (*c) { - case '#': out.setf(std::ios::showpoint | std::ios::showbase); continue; - case '0': - // overridden by left alignment ('-' flag) - if (!(out.flags() & std::ios::left)) { - // Use internal padding so that numeric values are - // formatted correctly, eg -00010 rather than 000-10 - out.fill('0'); - out.setf(std::ios::internal, std::ios::adjustfield); - } - continue; - case '-': - out.fill(' '); - out.setf(std::ios::left, std::ios::adjustfield); - continue; - case ' ': - // overridden by show positive sign, '+' flag. - if (!(out.flags() & std::ios::showpos)) - spacePadPositive = true; - continue; - case '+': - out.setf(std::ios::showpos); - spacePadPositive = false; - widthExtra = 1; - continue; - } - break; - } - // 2) Parse width - if (*c >= '0' && *c <= '9') { - widthSet = true; - out.width(parseIntAndAdvance(c)); - } - if (*c == '*') { - widthSet = true; - int width = 0; - if (argIndex < numFormatters) - width = formatters[argIndex++].toInt(); - else - TINYFORMAT_ERROR("tinyformat: Not enough arguments to read variable width"); - if (width < 0) { - // negative widths correspond to '-' flag set - out.fill(' '); - out.setf(std::ios::left, std::ios::adjustfield); - width = -width; - } - out.width(width); - ++c; - } - // 3) Parse precision - if (*c == '.') { - ++c; - int precision = 0; - if (*c == '*') { - ++c; - if (argIndex < numFormatters) - precision = formatters[argIndex++].toInt(); - else - TINYFORMAT_ERROR("tinyformat: Not enough arguments to read variable precision"); - } else { - if (*c >= '0' && *c <= '9') - precision = parseIntAndAdvance(c); - else if (*c == '-') // negative precisions ignored, treated as zero. - parseIntAndAdvance(++c); - } - out.precision(precision); - precisionSet = true; - } - // 4) Ignore any C99 length modifier - while (*c == 'l' || *c == 'h' || *c == 'L' || *c == 'j' || *c == 'z' || *c == 't') - ++c; - // 5) We're up to the conversion specifier character. - // Set stream flags based on conversion specifier (thanks to the - // boost::format class for forging the way here). - bool intConversion = false; - switch (*c) { - case 'u': - case 'd': - case 'i': - out.setf(std::ios::dec, std::ios::basefield); - intConversion = true; - break; - case 'o': - out.setf(std::ios::oct, std::ios::basefield); - intConversion = true; - break; - case 'X': out.setf(std::ios::uppercase); - case 'x': - case 'p': - out.setf(std::ios::hex, std::ios::basefield); - intConversion = true; - break; - case 'E': out.setf(std::ios::uppercase); - case 'e': - out.setf(std::ios::scientific, std::ios::floatfield); - out.setf(std::ios::dec, std::ios::basefield); - break; - case 'F': out.setf(std::ios::uppercase); - case 'f': out.setf(std::ios::fixed, std::ios::floatfield); break; - case 'G': out.setf(std::ios::uppercase); - case 'g': - out.setf(std::ios::dec, std::ios::basefield); - // As in boost::format, let stream decide float format. - out.flags(out.flags() & ~std::ios::floatfield); - break; - case 'a': - case 'A': - TINYFORMAT_ERROR( - "tinyformat: the %a and %A conversion specs " - "are not supported"); - break; - case 'c': - // Handled as special case inside formatValue() - break; - case 's': - if (precisionSet) - ntrunc = static_cast(out.precision()); - // Make %s print booleans as "true" and "false" - out.setf(std::ios::boolalpha); - break; - case 'n': - // Not supported - will cause problems! - TINYFORMAT_ERROR("tinyformat: %n conversion spec not supported"); - break; - case '\0': - TINYFORMAT_ERROR( - "tinyformat: Conversion spec incorrectly " - "terminated by end of string"); - return c; - } - if (intConversion && precisionSet && !widthSet) { - // "precision" for integers gives the minimum number of digits (to be - // padded with zeros on the left). This isn't really supported by the - // iostreams, but we can approximately simulate it with the width if - // the width isn't otherwise used. - out.width(out.precision() + widthExtra); - out.setf(std::ios::internal, std::ios::adjustfield); - out.fill('0'); - } - return c + 1; - } - - //------------------------------------------------------------------------------ - inline void formatImpl(std::ostream& out, const char* fmt, const detail::FormatArg* formatters, int numFormatters) { - // Saved stream state - std::streamsize origWidth = out.width(); - std::streamsize origPrecision = out.precision(); - std::ios::fmtflags origFlags = out.flags(); - char origFill = out.fill(); - - for (int argIndex = 0; argIndex < numFormatters; ++argIndex) { - // Parse the format string - fmt = printFormatStringLiteral(out, fmt); - bool spacePadPositive = false; - int ntrunc = -1; - const char* fmtEnd = streamStateFromFormat(out, spacePadPositive, ntrunc, fmt, formatters, argIndex, numFormatters); - if (argIndex >= numFormatters) { - // Check args remain after reading any variable width/precision - TINYFORMAT_ERROR("tinyformat: Not enough format arguments"); - return; - } - const FormatArg& arg = formatters[argIndex]; - // Format the arg into the stream. - if (!spacePadPositive) - arg.format(out, fmt, fmtEnd, ntrunc); - else { - // The following is a special case with no direct correspondence - // between stream formatting and the printf() behaviour. Simulate - // it crudely by formatting into a temporary string stream and - // munging the resulting string. - std::ostringstream tmpStream; - tmpStream.copyfmt(out); - tmpStream.setf(std::ios::showpos); - arg.format(tmpStream, fmt, fmtEnd, ntrunc); - std::string result = tmpStream.str(); // allocates... yuck. - for (size_t i = 0, iend = result.size(); i < iend; ++i) - if (result[i] == '+') - result[i] = ' '; - out << result; - } - fmt = fmtEnd; - } - - // Print remaining part of format string. - fmt = printFormatStringLiteral(out, fmt); - if (*fmt != '\0') - TINYFORMAT_ERROR("tinyformat: Too many conversion specifiers in format string"); - - // Restore stream state - out.width(origWidth); - out.precision(origPrecision); - out.flags(origFlags); - out.fill(origFill); - } - - } // namespace detail - - /// List of template arguments format(), held in a type-opaque way. - /// - /// A const reference to FormatList (typedef'd as FormatListRef) may be - /// conveniently used to pass arguments to non-template functions: All type - /// information has been stripped from the arguments, leaving just enough of a - /// common interface to perform formatting as required. - class FormatList { - public: - FormatList(detail::FormatArg* formatters, int N) : m_formatters(formatters), m_N(N) { - } - - friend void vformat(std::ostream& out, const char* fmt, const FormatList& list); - - private: - const detail::FormatArg* m_formatters; - int m_N; - }; - - /// Reference to type-opaque format list for passing to vformat() - typedef const FormatList& FormatListRef; - - namespace detail { - - // Format list subclass with fixed storage to avoid dynamic allocation - template - class FormatListN : public FormatList { - public: - template - FormatListN(const Args&... args) : FormatList(&m_formatterStore[0], N), m_formatterStore({FormatArg(args)...}) { - static_assert(sizeof...(args) == N, "Number of args must be N"); - } - - private: - std::array m_formatterStore; - }; - - // Special 0-arg version - MSVC says zero-sized C array in struct is nonstandard - template <> - class FormatListN<0> : public FormatList { - public: - FormatListN() : FormatList(0, 0) { - } - }; - - } // namespace detail - - //------------------------------------------------------------------------------ - // Primary API functions - - /// Make type-agnostic format list from list of template arguments. - /// - /// The exact return type of this function is an implementation detail and - /// shouldn't be relied upon. Instead it should be stored as a FormatListRef: - /// - /// FormatListRef formatList = makeFormatList( /*...*/ ); - template - detail::FormatListN makeFormatList(const Args&... args) { - return detail::FormatListN(args...); - } - - /// Format list of arguments to the stream according to the given format string. - /// - /// The name vformat() is chosen for the semantic similarity to vprintf(): the - /// list of format arguments is held in a single function argument. - inline void vformat(std::ostream& out, const char* fmt, FormatListRef list) { - detail::formatImpl(out, fmt, list.m_formatters, list.m_N); - } - - /// Format list of arguments to the stream according to given format string. - template - void format(std::ostream& out, const char* fmt, const Args&... args) { - vformat(out, fmt, makeFormatList(args...)); - } - - /// Format list of arguments according to the given format string and return - /// the result as a string. - template - std::string format(const char* fmt, const Args&... args) { - std::ostringstream oss; - format(oss, fmt, args...); - return oss.str(); - } - - /// Format list of arguments to std::cout, according to the given format string - template - void printf(const char* fmt, const Args&... args) { - format(std::cout, fmt, args...); - } - - template - void printfln(const char* fmt, const Args&... args) { - format(std::cout, fmt, args...); - std::cout << '\n'; - } - -} // namespace tinyformat - -#endif // TINYFORMAT_H_INCLUDED diff --git a/D3D11RenderSystem/src/BlueFramework/D3D11RenderSystem/D3D11EffectCore.cpp b/D3D11RenderSystem/src/BlueFramework/D3D11RenderSystem/D3D11EffectCore.cpp index 9ffbcbf..94005e9 100644 --- a/D3D11RenderSystem/src/BlueFramework/D3D11RenderSystem/D3D11EffectCore.cpp +++ b/D3D11RenderSystem/src/BlueFramework/D3D11RenderSystem/D3D11EffectCore.cpp @@ -323,7 +323,8 @@ D3D11PipelineState::D3D11PipelineState(D3D11RenderSystem* renderSystem, const bu rd.MultisampleEnable = renderSystem->getMSAAEnabled(); rd.AntialiasedLineEnable = false; - renderSystem_->getDevice()->CreateBlendState(&getD3D11BlendDesc(psd.blendStateDesc), &blendState_); + const auto blendStateDesc = getD3D11BlendDesc(psd.blendStateDesc); + renderSystem_->getDevice()->CreateBlendState(&blendStateDesc, &blendState_); renderSystem_->getDevice()->CreateRasterizerState(&rd, rasterizerState_.GetAddressOf()); } D3D11PipelineState::~D3D11PipelineState() { diff --git a/D3D12RenderSystem/src/BlueFramework/D3D12RenderSystem/D3D12RenderSystem.h b/D3D12RenderSystem/src/BlueFramework/D3D12RenderSystem/D3D12RenderSystem.h index 4ca8b09..452d12e 100644 --- a/D3D12RenderSystem/src/BlueFramework/D3D12RenderSystem/D3D12RenderSystem.h +++ b/D3D12RenderSystem/src/BlueFramework/D3D12RenderSystem/D3D12RenderSystem.h @@ -36,7 +36,9 @@ #include "BlueFramework/D3D12RenderSystem/namespace.h" #include "BlueFramework/Rasterizer/IRenderSystem.h" #include "BlueFramework/ImageProcessing/Image.h" + #include +#include BLUEFRAMEWORK_D3D12RENDERSYSTEM_NAMESPACE_BEGIN diff --git a/Engine/src/BlueFramework/Engine/ViewCube/ViewCube.cpp b/Engine/src/BlueFramework/Engine/ViewCube/ViewCube.cpp index 6e387ca..2f4c570 100644 --- a/Engine/src/BlueFramework/Engine/ViewCube/ViewCube.cpp +++ b/Engine/src/BlueFramework/Engine/ViewCube/ViewCube.cpp @@ -136,30 +136,35 @@ void BlueFramework::Engine::ViewCube::setPickIdBuffer(buw::ReferenceCounted(); - effect_.updateDescriptionBuffer(convert(desc_)); + updateEffectDescription(desc_); + effect_.updateDescriptionBuffer(buffer_); } void BlueFramework::Engine::ViewCube::updateTextColor(const QColor & color) { desc_.textColor = buw::Vector3f(color.redF(), color.greenF(), color.blueF()).cast(); - effect_.updateDescriptionBuffer(convert(desc_)); + updateEffectDescription(desc_); + effect_.updateDescriptionBuffer(buffer_); } void BlueFramework::Engine::ViewCube::updateHighlightColor(const QColor & color) { desc_.highlightColor = buw::Vector3f(color.redF(), color.greenF(), color.blueF()).cast(); - effect_.updateDescriptionBuffer(convert(desc_)); + updateEffectDescription(desc_); + effect_.updateDescriptionBuffer(buffer_); } void BlueFramework::Engine::ViewCube::updateSize(const float & size) { desc_.size = size; - effect_.updateDescriptionBuffer(convert(desc_)); + updateEffectDescription(desc_); + effect_.updateDescriptionBuffer(buffer_); } void BlueFramework::Engine::ViewCube::updateFaceColor(const QColor &color) { desc_.faceColor = buw::Vector3f(color.redF(), color.greenF(), color.blueF()).cast(); - effect_.updateDescriptionBuffer(convert(desc_)); + updateEffectDescription(desc_); + effect_.updateDescriptionBuffer(buffer_); } buw::Vector3f mapToColor(QString from) { @@ -394,6 +399,7 @@ void BlueFramework::Engine::ViewCube::viewCubeDescription::saveToFile(QString fi ofstream.close(); } + Description readDescription(QJsonObject from) { Description desc; @@ -459,16 +465,17 @@ void BlueFramework::Engine::ViewCube::setDescription(Description desc) { effect_.createCompassBuffers(vertices_compass, indices_compass); /*Pass the description on to the effect for rendering.*/ - ViewCubeEffect::DescriptionBuffer buffer; + /*ViewCubeEffect::DescriptionBuffer buffer; buffer.size[0] = desc_.size; buffer.bindingColor = desc_.bindingColor; buffer.faceColor = desc_.faceColor; buffer.highlightColor = desc_.highlightColor; buffer.selectedId = 0; buffer.textColor = desc_.textColor; - buffer.textureRange = desc_.outerBoundWidth + desc_.innerBoundHeight + 2.0f * desc_.innerBoundWidth; + buffer.textureRange = desc_.outerBoundWidth + desc_.innerBoundHeight + 2.0f * desc_.innerBoundWidth;*/ + updateEffectDescription(desc_); - effect_.updateDescriptionBuffer(convert(desc_)); + effect_.updateDescriptionBuffer(buffer_); /*Iterate over all faces and load the corresponding textures from the files specified in the description.*/ for(int face = 0; face < 6; ++face) { @@ -531,16 +538,14 @@ const buw::Vector3f BlueFramework::Engine::ViewCube::getViewDirection(eViewCubeO } /*Convert description from format used by ViewCube class to the one used by ViewCubeEffect.*/ -BlueFramework::Engine::ViewCubeEffect::DescriptionBuffer BlueFramework::Engine::ViewCube::convert(Description desc) { - ViewCubeEffect::DescriptionBuffer buffer; - buffer.size[0] = desc.size; - buffer.bindingColor = desc.bindingColor; - buffer.faceColor = desc.faceColor; - buffer.highlightColor = desc.highlightColor; - buffer.selectedId = effect_.getLastPickId(); - buffer.textColor = desc.textColor; - buffer.textureRange = desc.outerBoundWidth + desc.innerBoundHeight + 2.0f * desc.innerBoundWidth; - return buffer; +void BlueFramework::Engine::ViewCube::updateEffectDescription(const Description& desc) { + buffer_.size[0] = desc.size; + buffer_.bindingColor = desc.bindingColor; + buffer_.faceColor = desc.faceColor; + buffer_.highlightColor = desc.highlightColor; + buffer_.selectedId = effect_.getLastPickId(); + buffer_.textColor = desc.textColor; + buffer_.textureRange = desc.outerBoundWidth + desc.innerBoundHeight + 2.0f * desc.innerBoundWidth; } /*Load a description from file.*/ diff --git a/Engine/src/BlueFramework/Engine/ViewCube/ViewCube.h b/Engine/src/BlueFramework/Engine/ViewCube/ViewCube.h index 0d5e95b..a429002 100644 --- a/Engine/src/BlueFramework/Engine/ViewCube/ViewCube.h +++ b/Engine/src/BlueFramework/Engine/ViewCube/ViewCube.h @@ -90,7 +90,7 @@ class ViewCube : public QObject { std::string getFaceTexturePath(eFaceId face); - viewCubeDescription(){}; + viewCubeDescription() = default; void saveToFile(QString filename); }; @@ -164,11 +164,12 @@ public Q_SLOTS: const buw::Vector3f getViewDirection(eViewCubeOrientation orientation) const; - ViewCubeEffect::DescriptionBuffer convert(viewCubeDescription desc); + void updateEffectDescription(const viewCubeDescription& desc); private: viewCubeDescription desc_; ViewCubeEffect effect_; + ViewCubeEffect::DescriptionBuffer buffer_; // static std::multimap> mapping; buw::ReferenceCounted cameraController_; boost::signals2::connection connection_; diff --git a/GLRenderSystem/src/BlueFramework/GLRenderSystem/PipelineState.h b/GLRenderSystem/src/BlueFramework/GLRenderSystem/PipelineState.h index 8bcb9dc..a4bb43e 100644 --- a/GLRenderSystem/src/BlueFramework/GLRenderSystem/PipelineState.h +++ b/GLRenderSystem/src/BlueFramework/GLRenderSystem/PipelineState.h @@ -37,7 +37,7 @@ class RenderSystem; class PipelineState : public buw::IPipelineState, public std::enable_shared_from_this { public: - explicit PipelineState(RenderSystem* rs, buw::pipelineStateDescription const& psd) throw(...); + explicit PipelineState(RenderSystem* rs, buw::pipelineStateDescription const& psd) noexcept(false); virtual ~PipelineState(); void setActive(); diff --git a/GLRenderSystem/src/BlueFramework/GLRenderSystem/RenderSystem.h b/GLRenderSystem/src/BlueFramework/GLRenderSystem/RenderSystem.h index ccfafd8..1df2550 100644 --- a/GLRenderSystem/src/BlueFramework/GLRenderSystem/RenderSystem.h +++ b/GLRenderSystem/src/BlueFramework/GLRenderSystem/RenderSystem.h @@ -39,7 +39,10 @@ #include #define WIN32_LEAN_AND_MEAN -#define NOMINMAX +#ifndef NOMINMAX + #define NOMINMAX +#endif + #include BLUE_NAMESPACE_BLUEFRAMEWORK_GLRENDERSYSTEM_BEGIN diff --git a/GLRenderSystem/src/BlueFramework/GLRenderSystem/Utils.h b/GLRenderSystem/src/BlueFramework/GLRenderSystem/Utils.h index 972c0cf..fdd3577 100644 --- a/GLRenderSystem/src/BlueFramework/GLRenderSystem/Utils.h +++ b/GLRenderSystem/src/BlueFramework/GLRenderSystem/Utils.h @@ -37,7 +37,7 @@ void throwWithMessage( std::string const& sstrMsg, DWORD const nWinErrCode = ERROR_SUCCESS, GLenum const nGLErrCode = GL_NO_ERROR, - GLenum const nGLEWErrCode = GLEW_OK) throw(...); + GLenum const nGLEWErrCode = GLEW_OK) noexcept(false); void glClearError(); diff --git a/ImageProcessing/src/BlueFramework/ImageProcessing/Color.h b/ImageProcessing/src/BlueFramework/ImageProcessing/Color.h index 7f9c338..039e7aa 100644 --- a/ImageProcessing/src/BlueFramework/ImageProcessing/Color.h +++ b/ImageProcessing/src/BlueFramework/ImageProcessing/Color.h @@ -41,6 +41,8 @@ #include #include +#include + #include "BlueFramework/ImageProcessing/namespace.h" BLUEFRAMEWORK_IMAGEPROCESSING_NAMESPACE_BEGIN @@ -75,7 +77,7 @@ class Color { bool isValid() const { for (size_t i = 0; i < N; ++i) { T value = comp_[i]; - int cl = boost::math::fpclassify(value); + const int cl = boost::math::fpclassify(value); if (value < 0 || cl == FP_INFINITE || cl == FP_NAN) return false; @@ -210,7 +212,8 @@ struct Color { // template -struct Color { +class Color { +public: // Value type and number of components. typedef T ValueType; static const size_t Components = 3; @@ -251,24 +254,20 @@ struct Color { } // other color spaces - double getAlpha() const { + static double getAlpha() { return -1.0; } - double getBeta() const { + static double getBeta() { return -1.0; } - double getHue() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - - double r = (double)red / 255; - double g = (double)green / 255; - double b = (double)blue / 255; - double max = std::max(std::max(r, g), b); - double min = std::min(std::min(r, g), b); + double getHue() const { + const double r = red() / 255.0; + const double g = green() / 255.0; + const double b = blue() / 255.0; + const double max = std::max({r, g, b}); + const double min = std::min({r, g, b}); if (max == min) { return 0; @@ -282,38 +281,22 @@ struct Color { } double getSaturation() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; + const double max = std::max({red(), green(), blue()}) / 255.0; + const double min = std::min({red(), green(), blue()}) / 255.0; - double r = (double)red / 255; - double g = (double)green / 255; - double b = (double)blue / 255; - double max = std::max(std::max(r, g), b); - double min = std::min(std::min(r, g), b); - - if (max == 0) { + if (buw::doubleEqual(max, 0.0)) { return 0; - } else { - return (max - min) / max; } + return (max - min) / max; } double getBrightness() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - - double r = (double)red / 255; - double g = (double)green / 255; - double b = (double)blue / 255; - - return std::max(std::max(r, g), b); + return std::max({red(), green(), blue()}) / 255.0; } // needed for conversion from XYZ to sRGB // does not need to be accessible for the user - double gammaEncoding(double t) { + double gammaEncoding(double t) const { if (t > 0.0031308) { return 1.055 * pow(t, 1.0 / 2.4) - 0.055; } else { @@ -323,7 +306,7 @@ struct Color { // needed for conversion from sRGB to XYZ // does not need to be accessible for the user - double inverseGammaEncoding(double t) { + double inverseGammaEncoding(double t) const { if (t > 0.04045) { return pow((t + 0.055) / 1.055, 2.4); } else { @@ -332,44 +315,44 @@ struct Color { } // get the X-Value of XYZ from sRGB value - double getXYZ_X() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - - double r = inverseGammaEncoding((double)red / 255); - double g = inverseGammaEncoding((double)green / 255); - double b = inverseGammaEncoding((double)blue / 255); + double getXYZ_X() const { + const int red = (*this)[0]; + const int green = (*this)[1]; + const int blue = (*this)[2]; + + const double r = inverseGammaEncoding(static_cast(red) / 255); + const double g = inverseGammaEncoding(static_cast(green) / 255); + const double b = inverseGammaEncoding(static_cast(blue) / 255); return 0.4124564 * r + 0.3575761 * g + 0.1804375 * b; } // get the Y-Value of XYZ from sRGB value - double getXYZ_Y() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - - double r = inverseGammaEncoding((double)red / 255); - double g = inverseGammaEncoding((double)green / 255); - double b = inverseGammaEncoding((double)blue / 255); + double getXYZ_Y() const { + const int red = (*this)[0]; + const int green = (*this)[1]; + const int blue = (*this)[2]; + + const double r = inverseGammaEncoding(static_cast(red) / 255); + const double g = inverseGammaEncoding(static_cast(green) / 255); + const double b = inverseGammaEncoding(static_cast(blue) / 255); return 0.2126729 * r + 0.7151522 * g + 0.0721750 * b; } // get the Z-Value of XYZ from sRGB value - double getXYZ_Z() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - - double r = inverseGammaEncoding((double)red / 255); - double g = inverseGammaEncoding((double)green / 255); - double b = inverseGammaEncoding((double)blue / 255); + double getXYZ_Z() const { + const int red = (*this)[0]; + const int green = (*this)[1]; + const int blue = (*this)[2]; + + const double r = inverseGammaEncoding(static_cast(red) / 255); + const double g = inverseGammaEncoding(static_cast(green) / 255); + const double b = inverseGammaEncoding(static_cast(blue) / 255); return 0.0193339 * r + 0.1191920 * g + 0.9503041 * b; } // just a helper function that's needed for the L*ab-conversion // needn't to be accessible for the user - double LAB_helperFunction(double t) { + double LAB_helperFunction(double t) const { if (t > 0.008856) { return pow(t, 1.0 / 3.0); } else { @@ -378,39 +361,26 @@ struct Color { } // get the L-value of L*ab from sRGB value - double getLAB_L() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - - double Y = getXYZ_Y(red, green, blue); - std::cout << Y << std::endl; + double getLAB_L() const { + const double Y = getXYZ_Y(); return 116 * LAB_helperFunction(Y) - 16; } // get the a-value of L*ab from sRGB value - double getLAB_a(double x, double y) { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - + double getLAB_a(double x, double y) const { const double Yn = 1; const double Xn = x * (Yn / y); - double X = getXYZ_X(red, green, blue); - double Y = getXYZ_Y(red, green, blue); + const double X = getXYZ_X(); + const double Y = getXYZ_Y(); return 500 * (LAB_helperFunction(X / Xn) - LAB_helperFunction(Y / Yn)); } // get the b-value of L*ab from sRGB value - double getLAB_b(double x, double y) { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - + double getLAB_b(double x, double y) const { const double Yn = 1; const double Zn = (1 - x - y) * (Yn / y); - double Z = getXYZ_Z(red, green, blue); - double Y = getXYZ_Y(red, green, blue); + const double Z = getXYZ_Z(); + const double Y = getXYZ_Y(); return 200 * (LAB_helperFunction(Y / Yn) - LAB_helperFunction(Z / Zn)); } @@ -418,7 +388,7 @@ struct Color { bool isValid() const { for (int i = 0; i < 3; ++i) { T value = (*this)[i]; - int cl = boost::math::fpclassify(value); + const int cl = boost::math::fpclassify(value); if (value < 0 || cl == FP_INFINITE || cl == FP_NAN) return false; @@ -441,7 +411,8 @@ struct Color { // template -struct Color { +class Color { +public: // Value type and number of components. typedef T ValueType; static const size_t Components = 4; @@ -453,7 +424,8 @@ struct Color { Color(); // leave all components uninitialized explicit Color(const ValueType* rhs); // initialize with array of 4 scalars explicit Color(const ValueType val); // set all components to 'val' - Color(const Color& rgb, const ValueType a); + Color(const Color& rgb, const ValueType a) : r(rgb.r), g(rgb.g), b(rgb.b), a(a){}; + Color( // set individual components const ValueType r, const ValueType g, @@ -499,26 +471,26 @@ struct Color { } // other color spaces - double getAlpha() const { + static double getAlpha() { return -1.0; } - double getBeta() const { + static double getBeta() { return -1.0; } - double getHue() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; + double getHue() const { + const int red = (*this)[0]; + const int green = (*this)[1]; + const int blue = (*this)[2]; - double r = (double)red / 255; - double g = (double)green / 255; - double b = (double)blue / 255; - double max = std::max(std::max(r, g), b); - double min = std::min(std::min(r, g), b); + const double r = static_cast(red) / 255.0; + const double g = static_cast(green) / 255.0; + const double b = static_cast(blue) / 255.0; + const double max = std::max(std::max(r, g), b); + const double min = std::min(std::min(r, g), b); - if (max == min) { + if (buw::doubleEqual(max,min)) { return 0; } else if (max == r) { return 60 * ((g - b) / (max - min)); @@ -529,39 +501,31 @@ struct Color { } } - double getSaturation() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; + double getSaturation() const { + const int red = (*this)[0]; + const int green = (*this)[1]; + const int blue = (*this)[2]; - double r = (double)red / 255; - double g = (double)green / 255; - double b = (double)blue / 255; - double max = std::max(std::max(r, g), b); - double min = std::min(std::min(r, g), b); + const double r = static_cast(red) / 255; + const double g = static_cast(green) / 255; + const double b = static_cast(blue) / 255; + const double max = std::max(std::max(r, g), b); + const double min = std::min(std::min(r, g), b); - if (max == 0) { + if (buw::doubleEqual(max, 0.0)) { return 0; } else { return (max - min) / max; } } - double getBrightness() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - - double r = (double)red / 255; - double g = (double)green / 255; - double b = (double)blue / 255; - - return std::max(std::max(r, g), b); + double getBrightness() const { + return std::max({red(), green(), blue()}) / 255; } // needed for conversion from XYZ to sRGB // does not need to be accessable for the user - double gammaEncoding(double t) { + double gammaEncoding(double t) const { if (t > 0.0031308) { return 1.055 * pow(t, 1.0 / 2.4) - 0.055; } else { @@ -571,7 +535,7 @@ struct Color { // needed for conversion from sRGB to XYZ // does not need to be accessable for the user - double inverseGammaEncoding(double t) { + double inverseGammaEncoding(double t) const { if (t > 0.04045) { return pow((t + 0.055) / 1.055, 2.4); } else { @@ -580,44 +544,44 @@ struct Color { } // get the X-Value of XYZ from sRGB value - double getXYZ_X() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - - double r = inverseGammaEncoding((double)red / 255); - double g = inverseGammaEncoding((double)green / 255); - double b = inverseGammaEncoding((double)blue / 255); + double getXYZ_X() const { + const int red = (*this)[0]; + const int green = (*this)[1]; + const int blue = (*this)[2]; + + const double r = inverseGammaEncoding(static_cast(red) / 255); + const double g = inverseGammaEncoding(static_cast(green) / 255); + const double b = inverseGammaEncoding(static_cast(blue) / 255); return 0.4124564 * r + 0.3575761 * g + 0.1804375 * b; } // get the Y-Value of XYZ from sRGB value - double getXYZ_Y() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - - double r = inverseGammaEncoding((double)red / 255); - double g = inverseGammaEncoding((double)green / 255); - double b = inverseGammaEncoding((double)blue / 255); + double getXYZ_Y() const { + const int red = (*this)[0]; + const int green = (*this)[1]; + const int blue = (*this)[2]; + + const double r = inverseGammaEncoding(static_cast(red) / 255); + const double g = inverseGammaEncoding(static_cast(green) / 255); + const double b = inverseGammaEncoding(static_cast(blue) / 255); return 0.2126729 * r + 0.7151522 * g + 0.0721750 * b; } // get the Z-Value of XYZ from sRGB value - double getXYZ_Z() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - - double r = inverseGammaEncoding((double)red / 255); - double g = inverseGammaEncoding((double)green / 255); - double b = inverseGammaEncoding((double)blue / 255); + double getXYZ_Z() const { + const int red = (*this)[0]; + const int green = (*this)[1]; + const int blue = (*this)[2]; + + const double r = inverseGammaEncoding(static_cast(red) / 255); + const double g = inverseGammaEncoding(static_cast(green) / 255); + const double b = inverseGammaEncoding(static_cast(blue) / 255); return 0.0193339 * r + 0.1191920 * g + 0.9503041 * b; } // just a helper function that's needed for the L*ab-conversion // needn't to be accessable for the user - double LAB_helperFunction(double t) { + double LAB_helperFunction(double t) const { if (t > 0.008856) { return pow(t, 1.0 / 3.0); } else { @@ -626,39 +590,26 @@ struct Color { } // get the L-value of L*ab from sRGB value - double getLAB_L() { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - - double Y = getXYZ_Y(red, green, blue); - std::cout << Y << std::endl; + double getLAB_L() const { + const double Y = getXYZ_Y(); return 116 * LAB_helperFunction(Y) - 16; } // get the a-value of L*ab from sRGB value - double getLAB_a(double x, double y) { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - + double getLAB_a(const double x, const double y) const { const double Yn = 1; const double Xn = x * (Yn / y); - double X = getXYZ_X(red, green, blue); - double Y = getXYZ_Y(red, green, blue); + const double X = getXYZ_X(); + const double Y = getXYZ_Y(); return 500 * (LAB_helperFunction(X / Xn) - LAB_helperFunction(Y / Yn)); } // get the b-value of L*ab from sRGB value - double getLAB_b(double x, double y) { - int red = (*this)[0]; - int green = (*this)[1]; - int blue = (*this)[2]; - + double getLAB_b(double x, double y) const { const double Yn = 1; const double Zn = (1 - x - y) * (Yn / y); - double Z = getXYZ_Z(red, green, blue); - double Y = getXYZ_Y(red, green, blue); + const double Z = getXYZ_Z(); + const double Y = getXYZ_Y(); return 200 * (LAB_helperFunction(Y / Yn) - LAB_helperFunction(Z / Zn)); } @@ -906,7 +857,7 @@ inline Color clamp(const Color& c, const T min, const T max) { Color col; for (size_t i = 0; i < N; ++i) - col[i] = buw::clamp(c[i], min, max); + col[i] = clamp(c[i], min, max); return col; } @@ -1130,10 +1081,6 @@ template inline Color::Color(const ValueType val) : r(val), g(val), b(val), a(val) { } -template -inline Color::Color(const Color& rgb, const ValueType a_) : r(rgb.r), g(rgb.g), b(rgb.b), a(a_) { -} - template inline Color::Color(const ValueType r_, const ValueType g_, const ValueType b_, const ValueType a_) : r(r_), g(g_), b(b_), a(a_) { } @@ -1200,37 +1147,6 @@ inline std::ostream& operator<<(std::ostream& os, const Color BLUEFRAMEWORK_IMAGEPROCESSING_NAMESPACE_END -// -// Overload std::min() and std::max() for component-wise min/max operations on colors. -// - -// namespace std -//{ -// -// template -// inline foundation::Color min(const foundation::Color& lhs, const foundation::Color& rhs) -//{ -// foundation::Color col; -// -// for (size_t i = 0; i < N; ++i) -// col[i] = min(lhs[i], rhs[i]); -// -// return col; -//} -// -// template -// inline foundation::Color max(const foundation::Color& lhs, const foundation::Color& rhs) -//{ -// foundation::Color col; -// -// for (size_t i = 0; i < N; ++i) -// col[i] = max(lhs[i], rhs[i]); -// -// return col; -//} -// -//} // namespace std - BLUE_BLUEFRAMEWORK_IMAGEPROCESSING_EMBED_INTO_BUW_NAMESPACE(Color) BLUE_BLUEFRAMEWORK_IMAGEPROCESSING_EMBED_INTO_BUW_NAMESPACE(Color1b) BLUE_BLUEFRAMEWORK_IMAGEPROCESSING_EMBED_INTO_BUW_NAMESPACE(Color3b) diff --git a/Rasterizer/CMakeLists.txt b/Rasterizer/CMakeLists.txt index 169130b..41956f7 100644 --- a/Rasterizer/CMakeLists.txt +++ b/Rasterizer/CMakeLists.txt @@ -23,6 +23,7 @@ file(GLOB_RECURSE BlueFramework_Rasterizer_Headers src/BlueFramework/Raste source_group(BlueFramework\\Rasterizer\\Resources FILES ${BlueFramework_Rasterizer_Resources_Source}) source_group(BlueFramework\\Rasterizer FILES ${BlueFramework_Rasterizer_Source}) + add_library(BlueFramework.Rasterizer SHARED ${BlueFramework_Rasterizer_Descriptions_Source} ${BlueFramework_Rasterizer_Resources_Source} diff --git a/Rasterizer/src/BlueFramework/Rasterizer/IRenderSystem.cpp b/Rasterizer/src/BlueFramework/Rasterizer/IRenderSystem.cpp index b274051..0d34414 100644 --- a/Rasterizer/src/BlueFramework/Rasterizer/IRenderSystem.cpp +++ b/Rasterizer/src/BlueFramework/Rasterizer/IRenderSystem.cpp @@ -22,7 +22,7 @@ BLUEFRAMEWORK_RASTERIZER_NAMESPACE_BEGIN buw::ReferenceCounted createRenderSystem(const buw::renderSystemDescription& rsd) { - wchar_t* filename = nullptr; + const wchar_t* filename = nullptr; switch (rsd.renderAPI) { #ifdef _DEBUG diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/ClearScreen/ClearScreen.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/ClearScreen/ClearScreen.cpp index fe5d7fc..de76030 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/ClearScreen/ClearScreen.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/ClearScreen/ClearScreen.cpp @@ -82,7 +82,7 @@ public Q_SLOTS: void runClearScreenUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char* argv[] = { "ClearScreen.exe" }; + char* argv[] = {const_cast("ClearScreen.exe")}; QApplication app(argc, argv); Viewport v(renderAPI); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/CopyTextureRegion/CopyTextureRegion.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/CopyTextureRegion/CopyTextureRegion.cpp index d358fb6..e743851 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/CopyTextureRegion/CopyTextureRegion.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/CopyTextureRegion/CopyTextureRegion.cpp @@ -261,7 +261,7 @@ public Q_SLOTS: void runCopyTextureRegionUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char* argv[] = { "CopyTextureRegion.exe" }; + char* argv[] = { const_cast("CopyTextureRegion.exe") }; BlueFramework::Core::initializeLogSystem(false, true); QApplication app(argc, argv); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/DrawBoundingBox/DrawBoundingBox.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/DrawBoundingBox/DrawBoundingBox.cpp index 4134e16..3bba14c 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/DrawBoundingBox/DrawBoundingBox.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/DrawBoundingBox/DrawBoundingBox.cpp @@ -286,7 +286,7 @@ class Viewport : public QWidget { renderSystem_->present(); } - void Viewport::updateWorldBuffer() + void updateWorldBuffer() { WorldBuffer world; world.viewProjection = camera_->viewProjectionMatrix(); @@ -413,7 +413,7 @@ class Viewport : public QWidget { void runDrawBoundingBoxUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char *argv[] = { "DrawBoundingBox.exe" }; + char *argv[] = { const_cast("DrawBoundingBox.exe") }; QApplication app(argc, argv); BlueFramework::Core::initializeLogSystem(false, false); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/DrawTriangle/DrawTriangle.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/DrawTriangle/DrawTriangle.cpp index f1d1932..6a7aa83 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/DrawTriangle/DrawTriangle.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/DrawTriangle/DrawTriangle.cpp @@ -152,7 +152,7 @@ public Q_SLOTS: void runDrawTriangleUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char* argv[] = { "DrawTriangle.exe" }; + char* argv[] = {const_cast("DrawTriangle.exe")}; QApplication app(argc, argv); Viewport v(renderAPI); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/MSAA/MSAA.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/MSAA/MSAA.cpp index 3d15a2b..09ec9b4 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/MSAA/MSAA.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/MSAA/MSAA.cpp @@ -160,7 +160,7 @@ public Q_SLOTS: void runMSAAUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char* argv[] = { "MSAA.exe" }; + char* argv[] = {const_cast("MSAA.exe")}; QApplication app(argc, argv); Viewport v(renderAPI); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/PixelToaster/PixelToaster.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/PixelToaster/PixelToaster.cpp index cbe7820..62e6603 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/PixelToaster/PixelToaster.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/PixelToaster/PixelToaster.cpp @@ -234,7 +234,7 @@ public Q_SLOTS: void runPixelToasterUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char* argv[] = { "PixelToaster.exe" }; + char* argv[] = {const_cast("PixelToaster.exe")}; QApplication app(argc, argv); Viewport v(renderAPI); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/Skybox/Skybox.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/Skybox/Skybox.cpp index ff9e3c2..a5effa4 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/Skybox/Skybox.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/Skybox/Skybox.cpp @@ -244,7 +244,7 @@ class Viewport : public QWidget { return nullptr; } - void Viewport::updateWorldBuffer() { + void updateWorldBuffer() { WorldBuffer world; world.viewProjection = camera_->viewProjectionMatrix(); world.projection = camera_->frustum().projectionMatrix(); @@ -291,7 +291,7 @@ public Q_SLOTS: void runSkyboxUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char* argv[] = {"Skybox.exe"}; + char* argv[] = {const_cast("Skybox.exe")}; QApplication app(argc, argv); buw::loadWebResources("Data/resources.xml"); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/Snow/Snow.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/Snow/Snow.cpp index bc3223a..37dc731 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/Snow/Snow.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/Snow/Snow.cpp @@ -231,7 +231,7 @@ public Q_SLOTS: void runSnowUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char* argv[] = { "Snow.exe" }; + char* argv[] = {const_cast("Snow.exe")}; QApplication app(argc, argv); buw::loadWebResources("Data/resources.xml"); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/Testbed/Testbed.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/Testbed/Testbed.cpp index 7382d07..1aaa22f 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/Testbed/Testbed.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/Testbed/Testbed.cpp @@ -185,7 +185,7 @@ public Q_SLOTS: void runTestbedUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char *argv[] = { "Testbed.exe" }; + char *argv[] = { const_cast("Testbed.exe") }; QApplication app(argc, argv); buw::loadWebResources("Data/resources.xml"); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/TextRendering/TextRendering.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/TextRendering/TextRendering.cpp index 1ec08e4..b9c2e5b 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/TextRendering/TextRendering.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/TextRendering/TextRendering.cpp @@ -212,7 +212,7 @@ class Viewport : public QWidget { lastTick_ = current; } - void Viewport::updateWorldBuffer() { + void updateWorldBuffer() { WorldBuffer world; world.viewProjection = camera_->viewProjectionMatrix(); world.projection = camera_->frustum().projectionMatrix(); @@ -330,7 +330,7 @@ class Viewport : public QWidget { void runTextRenderingUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char *argv[] = { "TextRenderingTest.exe" }; + char *argv[] = {const_cast("TextRenderingTest.exe")}; QApplication app(argc, argv); //buw::loadWebResources("Data/resources.xml"); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/Texture1D/Texture1D.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/Texture1D/Texture1D.cpp index a0a104e..1c7c102 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/Texture1D/Texture1D.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/Texture1D/Texture1D.cpp @@ -171,7 +171,7 @@ class Viewport : public QWidget { void runTexture1DUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char* argv[] = { "Texture1D.exe" }; + char* argv[] = { const_cast("Texture1D.exe") }; QApplication app(argc, argv); buw::loadWebResources("Data/resources.xml"); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/Texture2D/Texture2D.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/Texture2D/Texture2D.cpp index 1c374eb..61dba07 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/Texture2D/Texture2D.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/Texture2D/Texture2D.cpp @@ -184,7 +184,7 @@ public Q_SLOTS: void runTexture2DUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char* argv[] = { "Texture2D.exe" }; + char* argv[] = { const_cast("Texture2D.exe") }; QApplication app(argc, argv); buw::loadWebResources("Data/resources.xml"); diff --git a/UnitTests/src/BlueFramework/UnitTests/Engine/ViewCube/ViewCubeTest.cpp b/UnitTests/src/BlueFramework/UnitTests/Engine/ViewCube/ViewCubeTest.cpp index c925705..19b81b9 100644 --- a/UnitTests/src/BlueFramework/UnitTests/Engine/ViewCube/ViewCubeTest.cpp +++ b/UnitTests/src/BlueFramework/UnitTests/Engine/ViewCube/ViewCubeTest.cpp @@ -179,7 +179,7 @@ class Viewport : public QWidget { lastTick_ = current; } - void Viewport::updateWorldBuffer() { + void updateWorldBuffer() { WorldBuffer world; world.viewProjection = camera_->viewProjectionMatrix(); world.projection = camera_->frustum().projectionMatrix(); @@ -317,7 +317,7 @@ public Q_SLOTS: void runViewCubeUnitTest(const buw::eRenderAPI renderAPI) { int argc = 1; - char *argv[] = { "ViewCube.exe" }; + char *argv[] = {const_cast ("ViewCube.exe")}; QApplication app(argc, argv); buw::loadWebResources("Data/resources.xml");