diff options
Diffstat (limited to '3rdparty/bx/src')
-rw-r--r-- | 3rdparty/bx/src/allocator.cpp | 75 | ||||
-rw-r--r-- | 3rdparty/bx/src/amalgamated.cpp | 11 | ||||
-rw-r--r-- | 3rdparty/bx/src/bx.cpp | 1 | ||||
-rw-r--r-- | 3rdparty/bx/src/bx_p.h | 44 | ||||
-rw-r--r-- | 3rdparty/bx/src/commandline.cpp | 29 | ||||
-rw-r--r-- | 3rdparty/bx/src/crtimpl.cpp | 361 | ||||
-rw-r--r-- | 3rdparty/bx/src/crtnone.cpp | 33 | ||||
-rw-r--r-- | 3rdparty/bx/src/debug.cpp | 46 | ||||
-rw-r--r-- | 3rdparty/bx/src/dtoa.cpp | 668 | ||||
-rw-r--r-- | 3rdparty/bx/src/easing.cpp | 64 | ||||
-rw-r--r-- | 3rdparty/bx/src/file.cpp | 408 | ||||
-rw-r--r-- | 3rdparty/bx/src/filepath.cpp | 543 | ||||
-rw-r--r-- | 3rdparty/bx/src/fpumath.cpp | 166 | ||||
-rw-r--r-- | 3rdparty/bx/src/hash.cpp | 151 | ||||
-rw-r--r-- | 3rdparty/bx/src/math.cpp | 744 | ||||
-rw-r--r-- | 3rdparty/bx/src/mutex.cpp | 11 | ||||
-rw-r--r-- | 3rdparty/bx/src/os.cpp | 256 | ||||
-rw-r--r-- | 3rdparty/bx/src/process.cpp | 169 | ||||
-rw-r--r-- | 3rdparty/bx/src/semaphore.cpp | 187 | ||||
-rw-r--r-- | 3rdparty/bx/src/settings.cpp | 214 | ||||
-rw-r--r-- | 3rdparty/bx/src/sort.cpp | 1 | ||||
-rw-r--r-- | 3rdparty/bx/src/string.cpp | 407 | ||||
-rw-r--r-- | 3rdparty/bx/src/thread.cpp | 37 | ||||
-rw-r--r-- | 3rdparty/bx/src/timer.cpp | 9 | ||||
-rw-r--r-- | 3rdparty/bx/src/url.cpp | 158 |
25 files changed, 3802 insertions, 991 deletions
diff --git a/3rdparty/bx/src/allocator.cpp b/3rdparty/bx/src/allocator.cpp new file mode 100644 index 00000000000..e3b5b37c826 --- /dev/null +++ b/3rdparty/bx/src/allocator.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/allocator.h> + +#include <malloc.h> + +#ifndef BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT +# define BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT 8 +#endif // BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT + +namespace bx +{ + DefaultAllocator::DefaultAllocator() + { + } + + DefaultAllocator::~DefaultAllocator() + { + } + + void* DefaultAllocator::realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) + { + if (0 == _size) + { + if (NULL != _ptr) + { + if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) + { + ::free(_ptr); + return NULL; + } + +# if BX_COMPILER_MSVC + BX_UNUSED(_file, _line); + _aligned_free(_ptr); +# else + bx::alignedFree(this, _ptr, _align, _file, _line); +# endif // BX_ + } + + return NULL; + } + else if (NULL == _ptr) + { + if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) + { + return ::malloc(_size); + } + +# if BX_COMPILER_MSVC + BX_UNUSED(_file, _line); + return _aligned_malloc(_size, _align); +# else + return bx::alignedAlloc(this, _size, _align, _file, _line); +# endif // BX_ + } + + if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) + { + return ::realloc(_ptr, _size); + } + +# if BX_COMPILER_MSVC + BX_UNUSED(_file, _line); + return _aligned_realloc(_ptr, _size, _align); +# else + return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line); +# endif // BX_ + } + +} // namespace bx diff --git a/3rdparty/bx/src/amalgamated.cpp b/3rdparty/bx/src/amalgamated.cpp index 1aeb2bb906d..7eaf04a58aa 100644 --- a/3rdparty/bx/src/amalgamated.cpp +++ b/3rdparty/bx/src/amalgamated.cpp @@ -3,17 +3,24 @@ * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ +#include "allocator.cpp" #include "bx.cpp" #include "commandline.cpp" -#include "crtimpl.cpp" #include "crtnone.cpp" #include "debug.cpp" #include "dtoa.cpp" -#include "fpumath.cpp" +#include "easing.cpp" +#include "file.cpp" +#include "filepath.cpp" +#include "hash.cpp" +#include "math.cpp" #include "mutex.cpp" #include "os.cpp" +#include "process.cpp" #include "semaphore.cpp" +#include "settings.cpp" #include "sort.cpp" #include "string.cpp" #include "thread.cpp" #include "timer.cpp" +#include "url.cpp" diff --git a/3rdparty/bx/src/bx.cpp b/3rdparty/bx/src/bx.cpp index 8a063c56de9..ae9743e45a7 100644 --- a/3rdparty/bx/src/bx.cpp +++ b/3rdparty/bx/src/bx.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/debug.h> #include <bx/readerwriter.h> diff --git a/3rdparty/bx/src/bx_p.h b/3rdparty/bx/src/bx_p.h new file mode 100644 index 00000000000..df37a2c5791 --- /dev/null +++ b/3rdparty/bx/src/bx_p.h @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#ifndef BX_P_H_HEADER_GUARD +#define BX_P_H_HEADER_GUARD + +#ifndef BX_CONFIG_DEBUG +# define BX_CONFIG_DEBUG 0 +#endif // BX_CONFIG_DEBUG + +#if BX_CONFIG_DEBUG +# define BX_TRACE _BX_TRACE +# define BX_WARN _BX_WARN +# define BX_CHECK _BX_CHECK +# define BX_CONFIG_ALLOCATOR_DEBUG 1 +#endif // BX_CONFIG_DEBUG + +#define _BX_TRACE(_format, ...) \ + BX_MACRO_BLOCK_BEGIN \ + bx::debugPrintf(__FILE__ "(" BX_STRINGIZE(__LINE__) "): BX " _format "\n", ##__VA_ARGS__); \ + BX_MACRO_BLOCK_END + +#define _BX_WARN(_condition, _format, ...) \ + BX_MACRO_BLOCK_BEGIN \ + if (!BX_IGNORE_C4127(_condition) ) \ + { \ + BX_TRACE("WARN " _format, ##__VA_ARGS__); \ + } \ + BX_MACRO_BLOCK_END + +#define _BX_CHECK(_condition, _format, ...) \ + BX_MACRO_BLOCK_BEGIN \ + if (!BX_IGNORE_C4127(_condition) ) \ + { \ + BX_TRACE("CHECK " _format, ##__VA_ARGS__); \ + bx::debugBreak(); \ + } \ + BX_MACRO_BLOCK_END + +#include <bx/bx.h> + +#endif // BX_P_H_HEADER_GUARD diff --git a/3rdparty/bx/src/commandline.cpp b/3rdparty/bx/src/commandline.cpp index 6ec2aadaaaf..de658261c41 100644 --- a/3rdparty/bx/src/commandline.cpp +++ b/3rdparty/bx/src/commandline.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/commandline.h> #include <bx/string.h> @@ -197,7 +198,7 @@ namespace bx const char* arg = findOption(_short, _long, 1); if (NULL != arg) { - _value = atoi(arg); + fromString(&_value, arg); return true; } @@ -209,7 +210,7 @@ namespace bx const char* arg = findOption(_short, _long, 1); if (NULL != arg) { - _value = atoi(arg); + fromString(&_value, arg); return true; } @@ -221,7 +222,7 @@ namespace bx const char* arg = findOption(_short, _long, 1); if (NULL != arg) { - _value = float(atof(arg)); + fromString(&_value, arg); return true; } @@ -233,7 +234,7 @@ namespace bx const char* arg = findOption(_short, _long, 1); if (NULL != arg) { - _value = atof(arg); + fromString(&_value, arg); return true; } @@ -245,11 +246,11 @@ namespace bx const char* arg = findOption(_short, _long, 1); if (NULL != arg) { - if ('0' == *arg || (0 == strincmp(arg, "false") ) ) + if ('0' == *arg || (0 == strCmpI(arg, "false") ) ) { _value = false; } - else if ('0' != *arg || (0 == strincmp(arg, "true") ) ) + else if ('0' != *arg || (0 == strCmpI(arg, "true") ) ) { _value = true; } @@ -262,7 +263,7 @@ namespace bx const char* CommandLine::find(int32_t _skip, const char _short, const char* _long, int32_t _numParams) const { - for (int32_t ii = 0; ii < m_argc; ++ii) + for (int32_t ii = 0; ii < m_argc && 0 != strCmp(m_argv[ii], "--"); ++ii) { const char* arg = m_argv[ii]; if ('-' == *arg) @@ -270,7 +271,7 @@ namespace bx ++arg; if (_short == *arg) { - if (1 == strnlen(arg) ) + if (1 == strLen(arg) ) { if (0 == _skip) { @@ -293,7 +294,7 @@ namespace bx } else if (NULL != _long && '-' == *arg - && 0 == strincmp(arg+1, _long) ) + && 0 == strCmpI(arg+1, _long) ) { if (0 == _skip) { @@ -319,4 +320,14 @@ namespace bx return NULL; } + int32_t CommandLine::getNum() const + { + return m_argc; + } + + char const* CommandLine::get(int32_t _idx) const + { + return m_argv[_idx]; + } + } // namespace bx diff --git a/3rdparty/bx/src/crtimpl.cpp b/3rdparty/bx/src/crtimpl.cpp deleted file mode 100644 index 064b9f6e3ad..00000000000 --- a/3rdparty/bx/src/crtimpl.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright 2010-2017 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#include <bx/crtimpl.h> -#include <stdio.h> - -#if BX_CONFIG_ALLOCATOR_CRT -# include <malloc.h> -#endif // BX_CONFIG_ALLOCATOR_CRT - -namespace bx -{ -#if BX_CONFIG_ALLOCATOR_CRT - CrtAllocator::CrtAllocator() - { - } - - CrtAllocator::~CrtAllocator() - { - } - - void* CrtAllocator::realloc(void* _ptr, size_t _size, size_t _align, const char* _file, uint32_t _line) - { - if (0 == _size) - { - if (NULL != _ptr) - { - if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) - { - ::free(_ptr); - return NULL; - } - -# if BX_COMPILER_MSVC - BX_UNUSED(_file, _line); - _aligned_free(_ptr); -# else - bx::alignedFree(this, _ptr, _align, _file, _line); -# endif // BX_ - } - - return NULL; - } - else if (NULL == _ptr) - { - if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) - { - return ::malloc(_size); - } - -# if BX_COMPILER_MSVC - BX_UNUSED(_file, _line); - return _aligned_malloc(_size, _align); -# else - return bx::alignedAlloc(this, _size, _align, _file, _line); -# endif // BX_ - } - - if (BX_CONFIG_ALLOCATOR_NATURAL_ALIGNMENT >= _align) - { - return ::realloc(_ptr, _size); - } - -# if BX_COMPILER_MSVC - BX_UNUSED(_file, _line); - return _aligned_realloc(_ptr, _size, _align); -# else - return bx::alignedRealloc(this, _ptr, _size, _align, _file, _line); -# endif // BX_ - } -#endif // BX_CONFIG_ALLOCATOR_CRT - -#if BX_CONFIG_CRT_FILE_READER_WRITER - -# if BX_CRT_MSVC -# define fseeko64 _fseeki64 -# define ftello64 _ftelli64 -# elif 0 \ - || BX_PLATFORM_ANDROID \ - || BX_PLATFORM_BSD \ - || BX_PLATFORM_IOS \ - || BX_PLATFORM_OSX \ - || BX_PLATFORM_QNX -# define fseeko64 fseeko -# define ftello64 ftello -# elif BX_PLATFORM_PS4 -# define fseeko64 fseek -# define ftello64 ftell -# endif // BX_ - - CrtFileReader::CrtFileReader() - : m_file(NULL) - { - } - - CrtFileReader::~CrtFileReader() - { - } - - bool CrtFileReader::open(const char* _filePath, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - if (NULL != m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open."); - return false; - } - - m_file = fopen(_filePath, "rb"); - if (NULL == m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileReader: Failed to open file."); - return false; - } - - return true; - } - - void CrtFileReader::close() - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fclose(file); - m_file = NULL; - } - - int64_t CrtFileReader::seek(int64_t _offset, Whence::Enum _whence) - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fseeko64(file, _offset, _whence); - return ftello64(file); - } - - int32_t CrtFileReader::read(void* _data, int32_t _size, Error* _err) - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - FILE* file = (FILE*)m_file; - int32_t size = (int32_t)fread(_data, 1, _size, file); - if (size != _size) - { - if (0 != feof(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "CrtFileReader: EOF."); - } - else if (0 != ferror(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "CrtFileReader: read error."); - } - - return size >= 0 ? size : 0; - } - - return size; - } - - CrtFileWriter::CrtFileWriter() - : m_file(NULL) - { - } - - CrtFileWriter::~CrtFileWriter() - { - } - - bool CrtFileWriter::open(const char* _filePath, bool _append, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - if (NULL != m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "CrtFileReader: File is already open."); - return false; - } - - m_file = fopen(_filePath, _append ? "ab" : "wb"); - - if (NULL == m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "CrtFileWriter: Failed to open file."); - return false; - } - - return true; - } - - void CrtFileWriter::close() - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fclose(file); - m_file = NULL; - } - - int64_t CrtFileWriter::seek(int64_t _offset, Whence::Enum _whence) - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - FILE* file = (FILE*)m_file; - fseeko64(file, _offset, _whence); - return ftello64(file); - } - - int32_t CrtFileWriter::write(const void* _data, int32_t _size, Error* _err) - { - BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - FILE* file = (FILE*)m_file; - int32_t size = (int32_t)fwrite(_data, 1, _size, file); - if (size != _size) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "CrtFileWriter: write failed."); - return size >= 0 ? size : 0; - } - - return size; - } -#endif // BX_CONFIG_CRT_FILE_READER_WRITER - -#if BX_CONFIG_CRT_PROCESS - -#if BX_CRT_MSVC -# define popen _popen -# define pclose _pclose -#endif // BX_CRT_MSVC - - ProcessReader::ProcessReader() - : m_file(NULL) - { - } - - ProcessReader::~ProcessReader() - { - BX_CHECK(NULL == m_file, "Process not closed!"); - } - - bool ProcessReader::open(const char* _command, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - if (NULL != m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessReader: File is already open."); - return false; - } - - m_file = popen(_command, "r"); - if (NULL == m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessReader: Failed to open process."); - return false; - } - - return true; - } - - void ProcessReader::close() - { - BX_CHECK(NULL != m_file, "Process not open!"); - FILE* file = (FILE*)m_file; - m_exitCode = pclose(file); - m_file = NULL; - } - - int32_t ProcessReader::read(void* _data, int32_t _size, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err); - - FILE* file = (FILE*)m_file; - int32_t size = (int32_t)fread(_data, 1, _size, file); - if (size != _size) - { - if (0 != feof(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "ProcessReader: EOF."); - } - else if (0 != ferror(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "ProcessReader: read error."); - } - - return size >= 0 ? size : 0; - } - - return size; - } - - int32_t ProcessReader::getExitCode() const - { - return m_exitCode; - } - - ProcessWriter::ProcessWriter() - : m_file(NULL) - { - } - - ProcessWriter::~ProcessWriter() - { - BX_CHECK(NULL == m_file, "Process not closed!"); - } - - bool ProcessWriter::open(const char* _command, bool, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); - - if (NULL != m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessWriter: File is already open."); - return false; - } - - m_file = popen(_command, "w"); - if (NULL == m_file) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessWriter: Failed to open process."); - return false; - } - - return true; - } - - void ProcessWriter::close() - { - BX_CHECK(NULL != m_file, "Process not open!"); - FILE* file = (FILE*)m_file; - m_exitCode = pclose(file); - m_file = NULL; - } - - int32_t ProcessWriter::write(const void* _data, int32_t _size, Error* _err) - { - BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err); - - FILE* file = (FILE*)m_file; - int32_t size = (int32_t)fwrite(_data, 1, _size, file); - if (size != _size) - { - if (0 != ferror(file) ) - { - BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "ProcessWriter: write error."); - } - - return size >= 0 ? size : 0; - } - - return size; - } - - int32_t ProcessWriter::getExitCode() const - { - return m_exitCode; - } -#endif // BX_CONFIG_CRT_PROCESS - -} // namespace bx diff --git a/3rdparty/bx/src/crtnone.cpp b/3rdparty/bx/src/crtnone.cpp index 0e88551b6f3..85028212133 100644 --- a/3rdparty/bx/src/crtnone.cpp +++ b/3rdparty/bx/src/crtnone.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/debug.h> #include <bx/sort.h> #include <bx/readerwriter.h> @@ -39,50 +40,50 @@ extern "C" int32_t memcmp(const void* _lhs, const void* _rhs, size_t _numBytes) extern "C" size_t strlen(const char* _str) { - return bx::strnlen(_str); + return bx::strLen(_str); } extern "C" size_t strnlen(const char* _str, size_t _max) { - return bx::strnlen(_str, _max); + return bx::strLen(_str, _max); } extern "C" void* strcpy(char* _dst, const char* _src) { - bx::strlncpy(_dst, INT32_MAX, _src, INT32_MAX); + bx::strCopy(_dst, INT32_MAX, _src, INT32_MAX); return _dst; } extern "C" void* strncpy(char* _dst, const char* _src, size_t _num) { - bx::strlncpy(_dst, INT32_MAX, _src, _num); + bx::strCopy(_dst, INT32_MAX, _src, _num); return _dst; } extern "C" char* strcat(char* _dst, const char* _src) { - bx::strlncat(_dst, INT32_MAX, _src, INT32_MAX); + bx::strCat(_dst, INT32_MAX, _src, INT32_MAX); return _dst; } extern "C" const char* strchr(const char* _str, int _ch) { - return bx::strnchr(_str, _ch); + return bx::strFind(_str, _ch); } extern "C" int32_t strcmp(const char* _lhs, const char* _rhs) { - return bx::strncmp(_lhs, _rhs); + return bx::strCmp(_lhs, _rhs); } extern "C" int32_t strncmp(const char* _lhs, const char* _rhs, size_t _max) { - return bx::strncmp(_lhs, _rhs, _max); + return bx::strCmp(_lhs, _rhs, _max); } extern "C" const char* strstr(const char* _str, const char* _find) { - return bx::strnstr(_str, _find); + return bx::strFind(_str, _find); } extern "C" void qsort(void* _base, size_t _num, size_t _size, bx::ComparisonFn _fn) @@ -244,14 +245,16 @@ extern "C" float fmodf(float _numer, float _denom) extern "C" int atoi(const char* _str) { - BX_UNUSED(_str); - return 0; + int32_t result = 0; + bx::fromString(&result, _str); + return result; } extern "C" double atof(const char* _str) { - BX_UNUSED(_str); - return 0.0; + double result = 0.0; + bx::fromString(&result, _str); + return result; } extern "C" struct DIR* opendir(const char* dirname) @@ -301,6 +304,10 @@ extern "C" int printf(const char* _format, ...) return -1; } +struct FILE +{ +}; + extern "C" int fprintf(FILE* _stream, const char* _format, ...) { BX_UNUSED(_stream, _format); diff --git a/3rdparty/bx/src/debug.cpp b/3rdparty/bx/src/debug.cpp index 5e52be86e88..d08fc9903e6 100644 --- a/3rdparty/bx/src/debug.cpp +++ b/3rdparty/bx/src/debug.cpp @@ -3,13 +3,17 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/debug.h> -#include <bx/string.h> // isPrint -#include <inttypes.h> // PRIx* +#include <bx/string.h> // isPrint +#include <bx/readerwriter.h> // WriterI +#include <inttypes.h> // PRIx* #if BX_PLATFORM_ANDROID # include <android/log.h> -#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE +#elif BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOXONE extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* _str); #elif BX_PLATFORM_IOS || BX_PLATFORM_OSX # if defined(__OBJC__) @@ -33,7 +37,7 @@ namespace bx #elif BX_CPU_ARM __builtin_trap(); // asm("bkpt 0"); -#elif !BX_PLATFORM_NACL && BX_CPU_X86 && (BX_COMPILER_GCC || BX_COMPILER_CLANG) +#elif BX_CPU_X86 && (BX_COMPILER_GCC || BX_COMPILER_CLANG) // NaCl doesn't like int 3: // NativeClient: NaCl module load failed: Validation failure. File violates Native Client safety rules. __asm__ ("int $3"); @@ -50,7 +54,9 @@ namespace bx # define BX_ANDROID_LOG_TAG "" # endif // BX_ANDROID_LOG_TAG __android_log_write(ANDROID_LOG_DEBUG, BX_ANDROID_LOG_TAG, _out); -#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE +#elif BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOXONE OutputDebugStringA(_out); #elif BX_PLATFORM_IOS || BX_PLATFORM_OSX # if defined(__OBJC__) @@ -125,7 +131,7 @@ namespace bx ascii[asciiPos] = '\0'; debugPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii); data += asciiPos; - hexPos = 0; + hexPos = 0; asciiPos = 0; } } @@ -142,4 +148,32 @@ namespace bx #undef HEX_DUMP_FORMAT } + class DebugWriter : public WriterI + { + virtual int32_t write(const void* _data, int32_t _size, Error* _err) override + { + BX_UNUSED(_err); + + int32_t total = 0; + + char temp[4096]; + while (total != _size) + { + uint32_t len = bx::uint32_min(sizeof(temp)-1, _size-total); + memCopy(temp, _data, len); + temp[len] = '\0'; + debugOutput(temp); + total += len; + } + + return total; + } + }; + + WriterI* getDebugOut() + { + static DebugWriter s_debugOut; + return &s_debugOut; + } + } // namespace bx diff --git a/3rdparty/bx/src/dtoa.cpp b/3rdparty/bx/src/dtoa.cpp index 98640ede20b..6945210dad1 100644 --- a/3rdparty/bx/src/dtoa.cpp +++ b/3rdparty/bx/src/dtoa.cpp @@ -3,8 +3,9 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/cpu.h> -#include <bx/fpumath.h> +#include <bx/math.h> #include <bx/string.h> #include <bx/uint32_t.h> @@ -12,28 +13,31 @@ namespace bx { - // https://github.com/miloyip/dtoa-benchmark - // - // Copyright (C) 2014 Milo Yip - // - // Permission is hereby granted, free of charge, to any person obtaining a copy - // of this software and associated documentation files (the "Software"), to deal - // in the Software without restriction, including without limitation the rights - // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - // copies of the Software, and to permit persons to whom the Software is - // furnished to do so, subject to the following conditions: - // - // The above copyright notice and this permission notice shall be included in - // all copies or substantial portions of the Software. - // - // 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE - // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - // THE SOFTWARE. - // + /* + * https://github.com/miloyip/dtoa-benchmark + * + * Copyright (C) 2014 Milo Yip + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + struct DiyFp { DiyFp() @@ -77,7 +81,7 @@ namespace bx DiyFp operator*(const DiyFp& rhs) const { - const uint64_t M32 = 0xFFFFFFFF; + const uint64_t M32 = UINT32_MAX; const uint64_t a = f >> 32; const uint64_t b = f & M32; const uint64_t c = rhs.f >> 32; @@ -105,23 +109,23 @@ namespace bx void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { - DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); - DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); + DiyFp pl = DiyFp( (f << 1) + 1, e - 1).NormalizeBoundary(); + DiyFp mi = (f == kDpHiddenBit) ? DiyFp( (f << 2) - 1, e - 2) : DiyFp( (f << 1) - 1, e - 1); mi.f <<= mi.e - pl.e; mi.e = pl.e; *plus = pl; *minus = mi; } -#define UINT64_C2(h, l) ((static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l)) +#define UINT64_C2(h, l) ( (static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l) ) - static const int32_t kDiySignificandSize = 64; - static const int32_t kDpSignificandSize = 52; - static const int32_t kDpExponentBias = 0x3FF + kDpSignificandSize; - static const int32_t kDpMinExponent = -kDpExponentBias; - static const uint64_t kDpExponentMask = UINT64_C2(0x7FF00000, 0x00000000); - static const uint64_t kDpSignificandMask = UINT64_C2(0x000FFFFF, 0xFFFFFFFF); - static const uint64_t kDpHiddenBit = UINT64_C2(0x00100000, 0x00000000); + static const int32_t kDiySignificandSize = 64; + static const int32_t kDpSignificandSize = 52; + static const int32_t kDpExponentBias = 0x3FF + kDpSignificandSize; + static const int32_t kDpMinExponent = -kDpExponentBias; + static const uint64_t kDpExponentMask = UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kDpSignificandMask = UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kDpHiddenBit = UINT64_C2(0x00100000, 0x00000000); uint64_t f; int32_t e; @@ -217,10 +221,10 @@ namespace bx k++; } - uint32_t index = static_cast<uint32_t>((k >> 3) + 1); - *K = -(-348 + static_cast<int32_t>(index << 3)); // decimal exponent no need lookup table + uint32_t index = static_cast<uint32_t>( (k >> 3) + 1); + *K = -(-348 + static_cast<int32_t>(index << 3) ); // decimal exponent no need lookup table - BX_CHECK(index < sizeof(s_kCachedPowers_F) / sizeof(s_kCachedPowers_F[0])); + BX_CHECK(index < sizeof(s_kCachedPowers_F) / sizeof(s_kCachedPowers_F[0]), ""); return DiyFp(s_kCachedPowers_F[index], s_kCachedPowers_E[index]); } @@ -228,7 +232,7 @@ namespace bx { while (rest < wp_w && delta - rest >= ten_kappa - && (rest + ten_kappa < wp_w || wp_w - rest > rest + ten_kappa - wp_w)) + && (rest + ten_kappa < wp_w || wp_w - rest > rest + ten_kappa - wp_w) ) { buffer[len - 1]--; rest += ten_kappa; @@ -256,7 +260,7 @@ namespace bx const DiyFp wp_w = Mp - W; uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e); uint64_t p2 = Mp.f & (one.f - 1); - int32_t kappa = static_cast<int32_t>(CountDecimalDigit32(p1)); + int32_t kappa = static_cast<int32_t>(CountDecimalDigit32(p1) ); *len = 0; while (kappa > 0) @@ -436,17 +440,17 @@ namespace bx if (isNan(_value) ) { - return (int32_t)strlncpy(_dst, _max, "nan") + sign; + return (int32_t)strCopy(_dst, _max, "nan") + sign; } else if (isInfinite(_value) ) { - return (int32_t)strlncpy(_dst, _max, "inf") + sign; + return (int32_t)strCopy(_dst, _max, "inf") + sign; } int32_t len; if (0.0 == _value) { - len = (int32_t)strlncpy(_dst, _max, "0.0"); + len = (int32_t)strCopy(_dst, _max, "0.0"); } else { @@ -557,4 +561,584 @@ namespace bx return toStringUnsigned(_dst, _max, _value, _base); } + /* + * https://github.com/grzegorz-kraszewski/stringtofloat/ + * + * MIT License + * + * Copyright (c) 2016 Grzegorz Kraszewski + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + /* + * IMPORTANT + * + * The code works in "round towards zero" mode. This is different from + * GCC standard library strtod(), which uses "round half to even" rule. + * Therefore it cannot be used as a direct drop-in replacement, as in + * some cases results will be different on the least significant bit of + * mantissa. Read more in the README.md file. + */ + +#define DIGITS 18 + +#define DOUBLE_PLUS_ZERO UINT64_C(0x0000000000000000) +#define DOUBLE_MINUS_ZERO UINT64_C(0x8000000000000000) +#define DOUBLE_PLUS_INFINITY UINT64_C(0x7ff0000000000000) +#define DOUBLE_MINUS_INFINITY UINT64_C(0xfff0000000000000) + + union HexDouble + { + double d; + uint64_t u; + }; + +#define lsr96(s2, s1, s0, d2, d1, d0) \ + d0 = ( (s0) >> 1) | ( ( (s1) & 1) << 31); \ + d1 = ( (s1) >> 1) | ( ( (s2) & 1) << 31); \ + d2 = (s2) >> 1; + +#define lsl96(s2, s1, s0, d2, d1, d0) \ + d2 = ( (s2) << 1) | ( ( (s1) & (1 << 31) ) >> 31); \ + d1 = ( (s1) << 1) | ( ( (s0) & (1 << 31) ) >> 31); \ + d0 = (s0) << 1; + + /* + * Undefine the below constant if your processor or compiler is slow + * at 64-bit arithmetic. This is a rare case however. 64-bit macros are + * better for deeply pipelined CPUs (no conditional execution), are + * very efficient for 64-bit processors and also fast on 32-bit processors + * featuring extended precision arithmetic (x86, PowerPC_32, M68k and probably + * more). + */ + +#define USE_64BIT_FOR_ADDSUB_MACROS 0 + +#if USE_64BIT_FOR_ADDSUB_MACROS + +#define add96(s2, s1, s0, d2, d1, d0) { \ + uint64_t w; \ + w = (uint64_t)(s0) + (uint64_t)(d0); \ + (s0) = w; \ + w >>= 32; \ + w += (uint64_t)(s1) + (uint64_t)(d1); \ + (s1) = w; \ + w >>= 32; \ + w += (uint64_t)(s2) + (uint64_t)(d2); \ + (s2) = w; } + +#define sub96(s2, s1, s0, d2, d1, d0) { \ + uint64_t w; \ + w = (uint64_t)(s0) - (uint64_t)(d0); \ + (s0) = w; \ + w >>= 32; \ + w += (uint64_t)(s1) - (uint64_t)(d1); \ + (s1) = w; \ + w >>= 32; \ + w += (uint64_t)(s2) - (uint64_t)(d2); \ + (s2) = w; } + +#else + +#define add96(s2, s1, s0, d2, d1, d0) { \ + uint32_t _x, _c; \ + _x = (s0); (s0) += (d0); \ + if ( (s0) < _x) _c = 1; else _c = 0; \ + _x = (s1); (s1) += (d1) + _c; \ + if ( ( (s1) < _x) || ( ( (s1) == _x) && _c) ) _c = 1; else _c = 0; \ + (s2) += (d2) + _c; } + +#define sub96(s2, s1, s0, d2, d1, d0) { \ + uint32_t _x, _c; \ + _x = (s0); (s0) -= (d0); \ + if ( (s0) > _x) _c = 1; else _c = 0; \ + _x = (s1); (s1) -= (d1) + _c; \ + if ( ( (s1) > _x) || ( ( (s1) == _x) && _c) ) _c = 1; else _c = 0; \ + (s2) -= (d2) + _c; } + +#endif /* USE_64BIT_FOR_ADDSUB_MACROS */ + + /* parser state machine states */ + +#define FSM_A 0 +#define FSM_B 1 +#define FSM_C 2 +#define FSM_D 3 +#define FSM_E 4 +#define FSM_F 5 +#define FSM_G 6 +#define FSM_H 7 +#define FSM_I 8 +#define FSM_STOP 9 + + /* The structure is filled by parser, then given to converter. */ + struct PrepNumber + { + int negative; /* 0 if positive number, 1 if negative */ + int32_t exponent; /* power of 10 exponent */ + uint64_t mantissa; /* integer mantissa */ + }; + + /* Possible parser return values. */ + +#define PARSER_OK 0 // parser finished OK +#define PARSER_PZERO 1 // no digits or number is smaller than +-2^-1022 +#define PARSER_MZERO 2 // number is negative, module smaller +#define PARSER_PINF 3 // number is higher than +HUGE_VAL +#define PARSER_MINF 4 // number is lower than -HUGE_VAL + + inline char next(const char*& _s, const char* _term) + { + return _s != _term + ? *_s++ + : '\0' + ; + } + + static int parser(const char* _s, const char* _term, PrepNumber* _pn) + { + int state = FSM_A; + int digx = 0; + char c = ' '; /* initial value for kicking off the state machine */ + int result = PARSER_OK; + int expneg = 0; + int32_t expexp = 0; + + while (state != FSM_STOP) // && _s != _term) + { + switch (state) + { + case FSM_A: + if (isSpace(c) ) + { + c = next(_s, _term); + } + else + { + state = FSM_B; + } + break; + + case FSM_B: + state = FSM_C; + + if (c == '+') + { + c = next(_s, _term); + } + else if (c == '-') + { + _pn->negative = 1; + c = next(_s, _term); + } + else if (isNumeric(c) ) + { + } + else if (c == '.') + { + } + else + { + state = FSM_STOP; + } + break; + + case FSM_C: + if (c == '0') + { + c = next(_s, _term); + } + else if (c == '.') + { + c = next(_s, _term); + state = FSM_D; + } + else + { + state = FSM_E; + } + break; + + case FSM_D: + if (c == '0') + { + c = next(_s, _term); + if (_pn->exponent > -2147483647) _pn->exponent--; + } + else + { + state = FSM_F; + } + break; + + case FSM_E: + if (isNumeric(c) ) + { + if (digx < DIGITS) + { + _pn->mantissa *= 10; + _pn->mantissa += c - '0'; + digx++; + } + else if (_pn->exponent < 2147483647) + { + _pn->exponent++; + } + + c = next(_s, _term); + } + else if (c == '.') + { + c = next(_s, _term); + state = FSM_F; + } + else + { + state = FSM_F; + } + break; + + case FSM_F: + if (isNumeric(c) ) + { + if (digx < DIGITS) + { + _pn->mantissa *= 10; + _pn->mantissa += c - '0'; + _pn->exponent--; + digx++; + } + + c = next(_s, _term); + } + else if ('e' == toLower(c) ) + { + c = next(_s, _term); + state = FSM_G; + } + else + { + state = FSM_G; + } + break; + + case FSM_G: + if (c == '+') + { + c = next(_s, _term); + } + else if (c == '-') + { + expneg = 1; + c = next(_s, _term); + } + + state = FSM_H; + break; + + case FSM_H: + if (c == '0') + { + c = next(_s, _term); + } + else + { + state = FSM_I; + } + break; + + case FSM_I: + if (isNumeric(c) ) + { + if (expexp < 214748364) + { + expexp *= 10; + expexp += c - '0'; + } + + c = next(_s, _term); + } + else + { + state = FSM_STOP; + } + break; + } + } + + if (expneg) + { + expexp = -expexp; + } + + _pn->exponent += expexp; + + if (_pn->mantissa == 0) + { + if (_pn->negative) + { + result = PARSER_MZERO; + } + else + { + result = PARSER_PZERO; + } + } + else if (_pn->exponent > 309) + { + if (_pn->negative) + { + result = PARSER_MINF; + } + else + { + result = PARSER_PINF; + } + } + else if (_pn->exponent < -328) + { + if (_pn->negative) + { + result = PARSER_MZERO; + } + else + { + result = PARSER_PZERO; + } + } + + return result; + } + + static double converter(PrepNumber* _pn) + { + int binexp = 92; + HexDouble hd; + uint32_t s2, s1, s0; /* 96-bit precision integer */ + uint32_t q2, q1, q0; /* 96-bit precision integer */ + uint32_t r2, r1, r0; /* 96-bit precision integer */ + uint32_t mask28 = UINT32_C(0xf) << 28; + + hd.u = 0; + + s0 = (uint32_t)(_pn->mantissa & UINT32_MAX); + s1 = (uint32_t)(_pn->mantissa >> 32); + s2 = 0; + + while (_pn->exponent > 0) + { + lsl96(s2, s1, s0, q2, q1, q0); // q = p << 1 + lsl96(q2, q1, q0, r2, r1, r0); // r = p << 2 + lsl96(r2, r1, r0, s2, s1, s0); // p = p << 3 + add96(s2, s1, s0, q2, q1, q0); // p = (p << 3) + (p << 1) + + _pn->exponent--; + + while (s2 & mask28) + { + lsr96(s2, s1, s0, q2, q1, q0); + binexp++; + s2 = q2; + s1 = q1; + s0 = q0; + } + } + + while (_pn->exponent < 0) + { + while (!(s2 & (1 << 31) ) ) + { + lsl96(s2, s1, s0, q2, q1, q0); + binexp--; + s2 = q2; + s1 = q1; + s0 = q0; + } + + q2 = s2 / 10; + r1 = s2 % 10; + r2 = (s1 >> 8) | (r1 << 24); + q1 = r2 / 10; + r1 = r2 % 10; + r2 = ( (s1 & 0xFF) << 16) | (s0 >> 16) | (r1 << 24); + r0 = r2 / 10; + r1 = r2 % 10; + q1 = (q1 << 8) | ( (r0 & 0x00FF0000) >> 16); + q0 = r0 << 16; + r2 = (s0 & UINT16_MAX) | (r1 << 16); + q0 |= r2 / 10; + s2 = q2; + s1 = q1; + s0 = q0; + + _pn->exponent++; + } + + if (s2 || s1 || s0) + { + while (!(s2 & mask28) ) + { + lsl96(s2, s1, s0, q2, q1, q0); + binexp--; + s2 = q2; + s1 = q1; + s0 = q0; + } + } + + binexp += 1023; + + if (binexp > 2046) + { + if (_pn->negative) + { + hd.u = DOUBLE_MINUS_INFINITY; + } + else + { + hd.u = DOUBLE_PLUS_INFINITY; + } + } + else if (binexp < 1) + { + if (_pn->negative) + { + hd.u = DOUBLE_MINUS_ZERO; + } + } + else if (s2) + { + uint64_t q; + uint64_t binexs2 = (uint64_t)binexp; + + binexs2 <<= 52; + q = ( (uint64_t)(s2 & ~mask28) << 24) + | ( ( (uint64_t)s1 + 128) >> 8) | binexs2; + + if (_pn->negative) + { + q |= (1ULL << 63); + } + + hd.u = q; + } + + return hd.d; + } + + int32_t toString(char* _out, int32_t _max, bool _value) + { + StringView str(_value ? "true" : "false"); + strCopy(_out, _max, str); + return str.getLength(); + } + + bool fromString(bool* _out, const StringView& _str) + { + char ch = toLower(_str.getPtr()[0]); + *_out = ch == 't' || ch == '1'; + return 0 != _str.getLength(); + } + + bool fromString(float* _out, const StringView& _str) + { + double dbl; + bool result = fromString(&dbl, _str); + *_out = float(dbl); + return result; + } + + bool fromString(double* _out, const StringView& _str) + { + PrepNumber pn; + pn.mantissa = 0; + pn.negative = 0; + pn.exponent = 0; + + HexDouble hd; + hd.u = DOUBLE_PLUS_ZERO; + + switch (parser(_str.getPtr(), _str.getTerm(), &pn) ) + { + case PARSER_OK: + *_out = converter(&pn); + break; + + case PARSER_PZERO: + *_out = hd.d; + break; + + case PARSER_MZERO: + hd.u = DOUBLE_MINUS_ZERO; + *_out = hd.d; + break; + + case PARSER_PINF: + hd.u = DOUBLE_PLUS_INFINITY; + *_out = hd.d; + break; + + case PARSER_MINF: + hd.u = DOUBLE_MINUS_INFINITY; + *_out = hd.d; + break; + } + + return true; + } + + bool fromString(int32_t* _out, const StringView& _str) + { + const char* str = _str.getPtr(); + const char* term = _str.getTerm(); + + str = strws(str); + char ch = *str++; + bool neg = false; + switch (ch) + { + case '-': + case '+': neg = '-' == ch; + break; + + default: + --str; + break; + } + + int32_t result = 0; + + for (ch = *str++; isNumeric(ch) && str <= term; ch = *str++) + { + result = 10*result - (ch - '0'); + } + + *_out = neg ? result : -result; + + return true; + } + + bool fromString(uint32_t* _out, const StringView& _str) + { + fromString( (int32_t*)_out, _str); + return true; + } + } // namespace bx diff --git a/3rdparty/bx/src/easing.cpp b/3rdparty/bx/src/easing.cpp new file mode 100644 index 00000000000..8ecb2d53299 --- /dev/null +++ b/3rdparty/bx/src/easing.cpp @@ -0,0 +1,64 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/easing.h> + +namespace bx +{ + static const EaseFn s_easeFunc[] = + { + easeLinear, + easeStep, + easeSmoothStep, + easeInQuad, + easeOutQuad, + easeInOutQuad, + easeOutInQuad, + easeInCubic, + easeOutCubic, + easeInOutCubic, + easeOutInCubic, + easeInQuart, + easeOutQuart, + easeInOutQuart, + easeOutInQuart, + easeInQuint, + easeOutQuint, + easeInOutQuint, + easeOutInQuint, + easeInSine, + easeOutSine, + easeInOutSine, + easeOutInSine, + easeInExpo, + easeOutExpo, + easeInOutExpo, + easeOutInExpo, + easeInCirc, + easeOutCirc, + easeInOutCirc, + easeOutInCirc, + easeInElastic, + easeOutElastic, + easeInOutElastic, + easeOutInElastic, + easeInBack, + easeOutBack, + easeInOutBack, + easeOutInBack, + easeInBounce, + easeOutBounce, + easeInOutBounce, + easeOutInBounce, + }; + BX_STATIC_ASSERT(BX_COUNTOF(s_easeFunc) == Easing::Count); + + EaseFn getEaseFunc(Easing::Enum _enum) + { + return s_easeFunc[_enum]; + } + +} // namespace bx diff --git a/3rdparty/bx/src/file.cpp b/3rdparty/bx/src/file.cpp new file mode 100644 index 00000000000..af74589c876 --- /dev/null +++ b/3rdparty/bx/src/file.cpp @@ -0,0 +1,408 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/file.h> + +#include <stdio.h> +#include <sys/stat.h> + +#ifndef BX_CONFIG_CRT_FILE_READER_WRITER +# define BX_CONFIG_CRT_FILE_READER_WRITER !(0 \ + || BX_CRT_NONE \ + ) +#endif // BX_CONFIG_CRT_FILE_READER_WRITER + +namespace bx +{ + class NoopWriterImpl : public FileWriterI + { + public: + NoopWriterImpl(void*) + { + } + + virtual ~NoopWriterImpl() + { + close(); + } + + virtual bool open(const FilePath& _filePath, bool _append, Error* _err) override + { + BX_UNUSED(_filePath, _append, _err); + return false; + } + + virtual void close() override + { + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override + { + BX_UNUSED(_offset, _whence); + return 0; + } + + virtual int32_t write(const void* _data, int32_t _size, Error* _err) override + { + BX_UNUSED(_data, _size, _err); + return 0; + } + }; + +#if BX_CONFIG_CRT_FILE_READER_WRITER + +# if BX_CRT_MSVC +# define fseeko64 _fseeki64 +# define ftello64 _ftelli64 +# elif 0 \ + || BX_PLATFORM_ANDROID \ + || BX_PLATFORM_BSD \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_QNX +# define fseeko64 fseeko +# define ftello64 ftello +# elif BX_PLATFORM_PS4 +# define fseeko64 fseek +# define ftello64 ftell +# endif // BX_ + + class FileReaderImpl : public FileReaderI + { + public: + FileReaderImpl(FILE* _file) + : m_file(_file) + , m_open(false) + { + } + + virtual ~FileReaderImpl() + { + close(); + } + + virtual bool open(const FilePath& _filePath, Error* _err) override + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + if (NULL != m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "FileReader: File is already open."); + return false; + } + + m_file = fopen(_filePath.get(), "rb"); + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "FileReader: Failed to open file."); + return false; + } + + m_open = true; + return true; + } + + virtual void close() override + { + if (m_open + && NULL != m_file) + { + fclose(m_file); + m_file = NULL; + } + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + fseeko64(m_file, _offset, _whence); + return ftello64(m_file); + } + + virtual int32_t read(void* _data, int32_t _size, Error* _err) override + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + int32_t size = (int32_t)fread(_data, 1, _size, m_file); + if (size != _size) + { + if (0 != feof(m_file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "FileReader: EOF."); + } + else if (0 != ferror(m_file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "FileReader: read error."); + } + + return size >= 0 ? size : 0; + } + + return size; + } + + private: + FILE* m_file; + bool m_open; + }; + + class FileWriterImpl : public FileWriterI + { + public: + FileWriterImpl(FILE* _file) + : m_file(_file) + , m_open(false) + { + } + + virtual ~FileWriterImpl() + { + close(); + } + + virtual bool open(const FilePath& _filePath, bool _append, Error* _err) override + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + if (NULL != m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "FileReader: File is already open."); + return false; + } + + m_file = fopen(_filePath.get(), _append ? "ab" : "wb"); + + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "FileWriter: Failed to open file."); + return false; + } + + m_open = true; + return true; + } + + virtual void close() override + { + if (m_open + && NULL != m_file) + { + fclose(m_file); + m_file = NULL; + } + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + fseeko64(m_file, _offset, _whence); + return ftello64(m_file); + } + + virtual int32_t write(const void* _data, int32_t _size, Error* _err) override + { + BX_CHECK(NULL != m_file, "Reader/Writer file is not open."); + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + int32_t size = (int32_t)fwrite(_data, 1, _size, m_file); + if (size != _size) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "FileWriter: write failed."); + return size >= 0 ? size : 0; + } + + return size; + } + + private: + FILE* m_file; + bool m_open; + }; + +#else + + class FileReaderImpl : public FileReaderI + { + public: + FileReaderImpl(void*) + { + } + + virtual ~FileReaderImpl() + { + close(); + } + + virtual bool open(const FilePath& _filePath, Error* _err) override + { + BX_UNUSED(_filePath, _err); + return false; + } + + virtual void close() override + { + } + + virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override + { + BX_UNUSED(_offset, _whence); + return 0; + } + + virtual int32_t read(void* _data, int32_t _size, Error* _err) override + { + BX_UNUSED(_data, _size, _err); + return 0; + } + }; + + typedef NoopWriterImpl FileWriterImpl; + +#endif // BX_CONFIG_CRT_FILE_READER_WRITER + + FileReader::FileReader() + { + BX_STATIC_ASSERT(sizeof(FileReaderImpl) <= sizeof(m_internal) ); + BX_PLACEMENT_NEW(m_internal, FileReaderImpl)(NULL); + } + + FileReader::~FileReader() + { + FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal); + impl->~FileReaderImpl(); + } + + bool FileReader::open(const FilePath& _filePath, Error* _err) + { + FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal); + return impl->open(_filePath, _err); + } + + void FileReader::close() + { + FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal); + impl->close(); + } + + int64_t FileReader::seek(int64_t _offset, Whence::Enum _whence) + { + FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal); + return impl->seek(_offset, _whence); + } + + int32_t FileReader::read(void* _data, int32_t _size, Error* _err) + { + FileReaderImpl* impl = reinterpret_cast<FileReaderImpl*>(m_internal); + return impl->read(_data, _size, _err); + } + + FileWriter::FileWriter() + { + BX_STATIC_ASSERT(sizeof(FileWriterImpl) <= sizeof(m_internal) ); + BX_PLACEMENT_NEW(m_internal, FileWriterImpl)(NULL); + } + + FileWriter::~FileWriter() + { + FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal); + impl->~FileWriterImpl(); + } + + bool FileWriter::open(const FilePath& _filePath, bool _append, Error* _err) + { + FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal); + return impl->open(_filePath, _append, _err); + } + + void FileWriter::close() + { + FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal); + impl->close(); + } + + int64_t FileWriter::seek(int64_t _offset, Whence::Enum _whence) + { + FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal); + return impl->seek(_offset, _whence); + } + + int32_t FileWriter::write(const void* _data, int32_t _size, Error* _err) + { + FileWriterImpl* impl = reinterpret_cast<FileWriterImpl*>(m_internal); + return impl->write(_data, _size, _err); + } + + ReaderI* getStdIn() + { + static FileReaderImpl s_stdIn(stdout); + return &s_stdIn; + } + + WriterI* getStdOut() + { + static FileWriterImpl s_stdOut(stdout); + return &s_stdOut; + } + + WriterI* getStdErr() + { + static FileWriterImpl s_stdOut(stderr); + return &s_stdOut; + } + + WriterI* getNullOut() + { + static NoopWriterImpl s_nullOut(NULL); + return &s_nullOut; + } + + bool stat(const FilePath& _filePath, FileInfo& _outFileInfo) + { + _outFileInfo.m_size = 0; + _outFileInfo.m_type = FileInfo::Count; + +#if BX_COMPILER_MSVC + struct ::_stat64 st; + int32_t result = ::_stat64(_filePath.get(), &st); + + if (0 != result) + { + return false; + } + + if (0 != (st.st_mode & _S_IFREG) ) + { + _outFileInfo.m_type = FileInfo::Regular; + } + else if (0 != (st.st_mode & _S_IFDIR) ) + { + _outFileInfo.m_type = FileInfo::Directory; + } +#else + struct ::stat st; + int32_t result = ::stat(_filePath.get(), &st); + if (0 != result) + { + return false; + } + + if (0 != (st.st_mode & S_IFREG) ) + { + _outFileInfo.m_type = FileInfo::Regular; + } + else if (0 != (st.st_mode & S_IFDIR) ) + { + _outFileInfo.m_type = FileInfo::Directory; + } +#endif // BX_COMPILER_MSVC + + _outFileInfo.m_size = st.st_size; + + return true; + } + +} // namespace bx diff --git a/3rdparty/bx/src/filepath.cpp b/3rdparty/bx/src/filepath.cpp new file mode 100644 index 00000000000..b8bbe279a59 --- /dev/null +++ b/3rdparty/bx/src/filepath.cpp @@ -0,0 +1,543 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/file.h> +#include <bx/os.h> +#include <bx/readerwriter.h> + +#include <stdio.h> // remove +#include <dirent.h> // opendir + +#if BX_CRT_MSVC +# include <direct.h> // _getcwd +#else +# include <sys/stat.h> // mkdir +# include <unistd.h> // getcwd +#endif // BX_CRT_MSVC + +#if BX_PLATFORM_WINDOWS +extern "C" __declspec(dllimport) unsigned long __stdcall GetTempPathA(unsigned long _max, char* _ptr); +#endif // BX_PLATFORM_WINDOWS + +namespace bx +{ + static bool isPathSeparator(char _ch) + { + return false + || '/' == _ch + || '\\' == _ch + ; + } + + static int32_t normalizeFilePath(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) + { + // Reference: Lexical File Names in Plan 9 or Getting Dot-Dot Right + // https://9p.io/sys/doc/lexnames.html + + const int32_t num = strLen(_src, _num); + + if (0 == num) + { + return strCopy(_dst, _dstSize, "."); + } + + int32_t size = 0; + + StaticMemoryBlockWriter writer(_dst, _dstSize); + Error err; + + int32_t idx = 0; + int32_t dotdot = 0; + + if (2 <= num + && ':' == _src[1]) + { + size += write(&writer, toUpper(_src[idx]), &err); + size += write(&writer, ':', &err); + idx += 2; + dotdot = size; + } + + const int32_t slashIdx = idx; + + bool rooted = isPathSeparator(_src[idx]); + if (rooted) + { + size += write(&writer, '/', &err); + ++idx; + dotdot = size; + } + + bool trailingSlash = false; + + while (idx < num && err.isOk() ) + { + switch (_src[idx]) + { + case '/': + case '\\': + ++idx; + trailingSlash = idx == num; + break; + + case '.': + if (idx+1 == num + || isPathSeparator(_src[idx+1]) ) + { + ++idx; + break; + } + + if ('.' == _src[idx+1] + && (idx+2 == num || isPathSeparator(_src[idx+2]) ) ) + { + idx += 2; + + if (dotdot < size) + { + for (--size + ; dotdot < size && !isPathSeparator(_dst[size]) + ; --size) + { + } + seek(&writer, size, Whence::Begin); + } + else if (!rooted) + { + if (0 < size) + { + size += write(&writer, '/', &err); + } + + size += write(&writer, "..", &err); + dotdot = size; + } + + break; + } + + BX_FALLTHROUGH; + + default: + if ( ( rooted && slashIdx+1 != size) + || (!rooted && 0 != size) ) + { + size += write(&writer, '/', &err); + } + + for (; idx < num && !isPathSeparator(_src[idx]); ++idx) + { + size += write(&writer, _src[idx], &err); + } + + break; + } + } + + if (0 == size) + { + size += write(&writer, '.', &err); + } + + if (trailingSlash) + { + size += write(&writer, '/', &err); + } + + write(&writer, '\0', &err); + + return size; + } + + static bool getEnv(const char* _name, FileInfo::Enum _type, char* _out, uint32_t* _inOutSize) + { + uint32_t len = *_inOutSize; + *_out = '\0'; + + if (getenv(_name, _out, &len) ) + { + FileInfo fi; + if (stat(_out, fi) + && _type == fi.m_type) + { + *_inOutSize = len; + return true; + } + } + + return false; + } + + static char* pwd(char* _buffer, uint32_t _size) + { +#if BX_PLATFORM_PS4 \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT + BX_UNUSED(_buffer, _size); + return NULL; +#elif BX_CRT_MSVC + return ::_getcwd(_buffer, (int32_t)_size); +#else + return ::getcwd(_buffer, _size); +#endif // BX_COMPILER_ + } + + static bool getCurrentPath(char* _out, uint32_t* _inOutSize) + { + uint32_t len = *_inOutSize; + pwd(_out, len); + *_inOutSize = strLen(_out); + return true; + } + + static bool getHomePath(char* _out, uint32_t* _inOutSize) + { + return false +#if BX_PLATFORM_WINDOWS + || getEnv("USERPROFILE", FileInfo::Directory, _out, _inOutSize) +#endif // BX_PLATFORM_WINDOWS + || getEnv("HOME", FileInfo::Directory, _out, _inOutSize) + ; + } + + static bool getTempPath(char* _out, uint32_t* _inOutSize) + { +#if BX_PLATFORM_WINDOWS + uint32_t len = ::GetTempPathA(*_inOutSize, _out); + bool result = len != 0 && len < *_inOutSize; + *_inOutSize = len; + return result; +#else + static const char* s_tmp[] = + { + "TMPDIR", + "TMP", + "TEMP", + "TEMPDIR", + + NULL + }; + + for (const char** tmp = s_tmp; *tmp != NULL; ++tmp) + { + uint32_t len = *_inOutSize; + *_out = '\0'; + bool ok = getEnv(*tmp, FileInfo::Directory, _out, &len); + + if (ok + && len != 0 + && len < *_inOutSize) + { + *_inOutSize = len; + return ok; + } + } + + FileInfo fi; + if (stat("/tmp", fi) + && FileInfo::Directory == fi.m_type) + { + strCopy(_out, *_inOutSize, "/tmp"); + *_inOutSize = 4; + return true; + } + + return false; +#endif // BX_PLATFORM_* + } + + FilePath::FilePath() + { + set(""); + } + + FilePath::FilePath(Dir::Enum _dir) + { + set(_dir); + } + + FilePath::FilePath(const char* _rhs) + { + set(_rhs); + } + + FilePath::FilePath(const StringView& _filePath) + { + set(_filePath); + } + + FilePath& FilePath::operator=(const StringView& _rhs) + { + set(_rhs); + return *this; + } + + void FilePath::set(Dir::Enum _dir) + { + char tmp[kMaxFilePath]; + uint32_t len = BX_COUNTOF(tmp); + + switch (_dir) + { + case Dir::Current: + getCurrentPath(tmp, &len); + break; + + case Dir::Temp: + getTempPath(tmp, &len); + break; + + case Dir::Home: + getHomePath(tmp, &len); + break; + + default: + len = 0; + break; + } + + set(StringView(tmp, len) ); + } + + void FilePath::set(const StringView& _filePath) + { + normalizeFilePath( + m_filePath + , BX_COUNTOF(m_filePath) + , _filePath.getPtr() + , _filePath.getLength() + ); + } + + void FilePath::join(const StringView& _str) + { + char tmp[kMaxFilePath]; + strCopy(tmp, BX_COUNTOF(tmp), m_filePath); + strCat(tmp, BX_COUNTOF(tmp), "/"); + strCat(tmp, BX_COUNTOF(tmp), _str); + set(tmp); + } + + const char* FilePath::get() const + { + return m_filePath; + } + + const StringView FilePath::getPath() const + { + const char* end = strRFind(m_filePath, '/'); + if (NULL != end) + { + return StringView(m_filePath, end+1); + } + + return StringView(); + } + + const StringView FilePath::getFileName() const + { + const char* fileName = strRFind(m_filePath, '/'); + if (NULL != fileName) + { + return StringView(fileName+1); + } + + return get(); + } + + const StringView FilePath::getBaseName() const + { + const StringView fileName = getFileName(); + if (!fileName.isEmpty() ) + { + const char* ext = strFind(fileName, '.'); + if (ext != NULL) + { + return StringView(fileName.getPtr(), ext); + } + + return fileName; + } + + return StringView(); + } + + const StringView FilePath::getExt() const + { + const StringView fileName = getFileName(); + if (!fileName.isEmpty() ) + { + const char* ext = strFind(fileName, '.'); + return StringView(ext); + } + + return StringView(); + } + + bool FilePath::isAbsolute() const + { + return '/' == m_filePath[0] // no drive letter + || (':' == m_filePath[1] && '/' == m_filePath[2]) // with drive letter + ; + } + + bool make(const FilePath& _filePath, Error* _err) + { + BX_ERROR_SCOPE(_err); + + if (!_err->isOk() ) + { + return false; + } + +#if BX_CRT_MSVC + int32_t result = ::_mkdir(_filePath.get() ); +#elif BX_CRT_MINGW + int32_t result = ::mkdir(_filePath.get()); +#else + int32_t result = ::mkdir(_filePath.get(), 0700); +#endif // BX_CRT_MSVC + + if (0 != result) + { + BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process."); + return false; + } + + return true; + } + + bool makeAll(const FilePath& _filePath, Error* _err) + { + BX_ERROR_SCOPE(_err); + + if (!_err->isOk() ) + { + return false; + } + + FileInfo fi; + + if (stat(_filePath, fi) ) + { + if (FileInfo::Directory == fi.m_type) + { + return true; + } + + BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory."); + return false; + } + + const StringView dir = strRTrim(_filePath.get(), "/"); + const char* slash = strRFind(dir, '/'); + + if (NULL != slash + && slash - dir.getPtr() > 1) + { + if (!makeAll(StringView(dir.getPtr(), slash), _err) ) + { + return false; + } + } + + FilePath path(dir); + return make(path, _err); + } + + bool remove(const FilePath& _filePath, Error* _err) + { + BX_ERROR_SCOPE(_err); + + if (!_err->isOk() ) + { + return false; + } + +#if BX_CRT_MSVC + int32_t result = -1; + FileInfo fi; + if (stat(_filePath, fi) ) + { + if (FileInfo::Directory == fi.m_type) + { + result = ::_rmdir(_filePath.get() ); + } + else + { + result = ::remove(_filePath.get() ); + } + } +#else + int32_t result = ::remove(_filePath.get() ); +#endif // BX_CRT_MSVC + + if (0 != result) + { + BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process."); + return false; + } + + return true; + } + + bool removeAll(const FilePath& _filePath, Error* _err) + { + BX_ERROR_SCOPE(_err); + + if (remove(_filePath, _err) ) + { + return true; + } + + _err->reset(); + + FileInfo fi; + + if (!stat(_filePath, fi) ) + { + BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process."); + return false; + } + + if (FileInfo::Directory != fi.m_type) + { + BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory."); + return false; + } + +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX || BX_PLATFORM_OSX + DIR* dir = opendir(_filePath.get() ); + if (NULL == dir) + { + BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory."); + return false; + } + + for (dirent* item = readdir(dir); NULL != item; item = readdir(dir) ) + { + if (0 == strCmp(item->d_name, ".") + || 0 == strCmp(item->d_name, "..") ) + { + continue; + } + + FilePath path(_filePath); + path.join(item->d_name); + if (!removeAll(path, _err) ) + { + _err->reset(); + break; + } + } + + closedir(dir); +#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_LINUX || BX_PLATFORM_OSX + + return remove(_filePath, _err); + } + +} // namespace bx diff --git a/3rdparty/bx/src/fpumath.cpp b/3rdparty/bx/src/fpumath.cpp deleted file mode 100644 index e957ef9e960..00000000000 --- a/3rdparty/bx/src/fpumath.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2011-2017 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#include <bx/fpumath.h> -#include <math.h> - -namespace bx -{ - const float pi = 3.14159265358979323846f; - const float invPi = 1.0f/3.14159265358979323846f; - const float piHalf = 1.57079632679489661923f; - const float sqrt2 = 1.41421356237309504880f; -#if BX_COMPILER_MSVC - const float huge = float(HUGE_VAL); -#else - const float huge = HUGE_VALF; -#endif // BX_COMPILER_MSVC - - float fabsolute(float _a) - { - return ::fabsf(_a); - } - - float fsin(float _a) - { - return ::sinf(_a); - } - - float fasin(float _a) - { - return ::asinf(_a); - } - - float fcos(float _a) - { - return ::cosf(_a); - } - - float ftan(float _a) - { - return ::tanf(_a); - } - - float facos(float _a) - { - return ::acosf(_a); - } - - float fatan2(float _y, float _x) - { - return ::atan2f(_y, _x); - } - - float fpow(float _a, float _b) - { - return ::powf(_a, _b); - } - - float flog(float _a) - { - return ::logf(_a); - } - - float fsqrt(float _a) - { - return ::sqrtf(_a); - } - - float ffloor(float _f) - { - return ::floorf(_f); - } - - float fceil(float _f) - { - return ::ceilf(_f); - } - - float fmod(float _a, float _b) - { - return ::fmodf(_a, _b); - } - - void mtx3Inverse(float* _result, const float* _a) - { - float xx = _a[0]; - float xy = _a[1]; - float xz = _a[2]; - float yx = _a[3]; - float yy = _a[4]; - float yz = _a[5]; - float zx = _a[6]; - float zy = _a[7]; - float zz = _a[8]; - - float det = 0.0f; - det += xx * (yy*zz - yz*zy); - det -= xy * (yx*zz - yz*zx); - det += xz * (yx*zy - yy*zx); - - float invDet = 1.0f/det; - - _result[0] = +(yy*zz - yz*zy) * invDet; - _result[1] = -(xy*zz - xz*zy) * invDet; - _result[2] = +(xy*yz - xz*yy) * invDet; - - _result[3] = -(yx*zz - yz*zx) * invDet; - _result[4] = +(xx*zz - xz*zx) * invDet; - _result[5] = -(xx*yz - xz*yx) * invDet; - - _result[6] = +(yx*zy - yy*zx) * invDet; - _result[7] = -(xx*zy - xy*zx) * invDet; - _result[8] = +(xx*yy - xy*yx) * invDet; - } - - void mtxInverse(float* _result, const float* _a) - { - float xx = _a[ 0]; - float xy = _a[ 1]; - float xz = _a[ 2]; - float xw = _a[ 3]; - float yx = _a[ 4]; - float yy = _a[ 5]; - float yz = _a[ 6]; - float yw = _a[ 7]; - float zx = _a[ 8]; - float zy = _a[ 9]; - float zz = _a[10]; - float zw = _a[11]; - float wx = _a[12]; - float wy = _a[13]; - float wz = _a[14]; - float ww = _a[15]; - - float det = 0.0f; - det += xx * (yy*(zz*ww - zw*wz) - yz*(zy*ww - zw*wy) + yw*(zy*wz - zz*wy) ); - det -= xy * (yx*(zz*ww - zw*wz) - yz*(zx*ww - zw*wx) + yw*(zx*wz - zz*wx) ); - det += xz * (yx*(zy*ww - zw*wy) - yy*(zx*ww - zw*wx) + yw*(zx*wy - zy*wx) ); - det -= xw * (yx*(zy*wz - zz*wy) - yy*(zx*wz - zz*wx) + yz*(zx*wy - zy*wx) ); - - float invDet = 1.0f/det; - - _result[ 0] = +(yy*(zz*ww - wz*zw) - yz*(zy*ww - wy*zw) + yw*(zy*wz - wy*zz) ) * invDet; - _result[ 1] = -(xy*(zz*ww - wz*zw) - xz*(zy*ww - wy*zw) + xw*(zy*wz - wy*zz) ) * invDet; - _result[ 2] = +(xy*(yz*ww - wz*yw) - xz*(yy*ww - wy*yw) + xw*(yy*wz - wy*yz) ) * invDet; - _result[ 3] = -(xy*(yz*zw - zz*yw) - xz*(yy*zw - zy*yw) + xw*(yy*zz - zy*yz) ) * invDet; - - _result[ 4] = -(yx*(zz*ww - wz*zw) - yz*(zx*ww - wx*zw) + yw*(zx*wz - wx*zz) ) * invDet; - _result[ 5] = +(xx*(zz*ww - wz*zw) - xz*(zx*ww - wx*zw) + xw*(zx*wz - wx*zz) ) * invDet; - _result[ 6] = -(xx*(yz*ww - wz*yw) - xz*(yx*ww - wx*yw) + xw*(yx*wz - wx*yz) ) * invDet; - _result[ 7] = +(xx*(yz*zw - zz*yw) - xz*(yx*zw - zx*yw) + xw*(yx*zz - zx*yz) ) * invDet; - - _result[ 8] = +(yx*(zy*ww - wy*zw) - yy*(zx*ww - wx*zw) + yw*(zx*wy - wx*zy) ) * invDet; - _result[ 9] = -(xx*(zy*ww - wy*zw) - xy*(zx*ww - wx*zw) + xw*(zx*wy - wx*zy) ) * invDet; - _result[10] = +(xx*(yy*ww - wy*yw) - xy*(yx*ww - wx*yw) + xw*(yx*wy - wx*yy) ) * invDet; - _result[11] = -(xx*(yy*zw - zy*yw) - xy*(yx*zw - zx*yw) + xw*(yx*zy - zx*yy) ) * invDet; - - _result[12] = -(yx*(zy*wz - wy*zz) - yy*(zx*wz - wx*zz) + yz*(zx*wy - wx*zy) ) * invDet; - _result[13] = +(xx*(zy*wz - wy*zz) - xy*(zx*wz - wx*zz) + xz*(zx*wy - wx*zy) ) * invDet; - _result[14] = -(xx*(yy*wz - wy*yz) - xy*(yx*wz - wx*yz) + xz*(yx*wy - wx*yy) ) * invDet; - _result[15] = +(xx*(yy*zz - zy*yz) - xy*(yx*zz - zx*yz) + xz*(yx*zy - zx*yy) ) * invDet; - } - -} // namespace bx diff --git a/3rdparty/bx/src/hash.cpp b/3rdparty/bx/src/hash.cpp new file mode 100644 index 00000000000..4335443f245 --- /dev/null +++ b/3rdparty/bx/src/hash.cpp @@ -0,0 +1,151 @@ +/* + * Copyright 2011-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/hash.h> + +namespace bx +{ + +static const uint32_t s_crcTableIeee[] = +{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; +BX_STATIC_ASSERT(BX_COUNTOF(s_crcTableIeee) == 256); + +static const uint32_t s_crcTableCastagnoli[] = +{ + 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, + 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, + 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384, + 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b, + 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, + 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa, + 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a, + 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, + 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957, + 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198, + 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, + 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7, + 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789, + 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, + 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6, + 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829, + 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, + 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c, + 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc, + 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, + 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d, + 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982, + 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, + 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed, + 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f, + 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, + 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540, + 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f, + 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, + 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e, + 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e, + 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351, +}; +BX_STATIC_ASSERT(BX_COUNTOF(s_crcTableCastagnoli) == 256); + +static const uint32_t s_crcTableKoopman[] = +{ + 0x00000000, 0x9695c4ca, 0xfb4839c9, 0x6dddfd03, 0x20f3c3cf, 0xb6660705, 0xdbbbfa06, 0x4d2e3ecc, + 0x41e7879e, 0xd7724354, 0xbaafbe57, 0x2c3a7a9d, 0x61144451, 0xf781809b, 0x9a5c7d98, 0x0cc9b952, + 0x83cf0f3c, 0x155acbf6, 0x788736f5, 0xee12f23f, 0xa33cccf3, 0x35a90839, 0x5874f53a, 0xcee131f0, + 0xc22888a2, 0x54bd4c68, 0x3960b16b, 0xaff575a1, 0xe2db4b6d, 0x744e8fa7, 0x199372a4, 0x8f06b66e, + 0xd1fdae25, 0x47686aef, 0x2ab597ec, 0xbc205326, 0xf10e6dea, 0x679ba920, 0x0a465423, 0x9cd390e9, + 0x901a29bb, 0x068fed71, 0x6b521072, 0xfdc7d4b8, 0xb0e9ea74, 0x267c2ebe, 0x4ba1d3bd, 0xdd341777, + 0x5232a119, 0xc4a765d3, 0xa97a98d0, 0x3fef5c1a, 0x72c162d6, 0xe454a61c, 0x89895b1f, 0x1f1c9fd5, + 0x13d52687, 0x8540e24d, 0xe89d1f4e, 0x7e08db84, 0x3326e548, 0xa5b32182, 0xc86edc81, 0x5efb184b, + 0x7598ec17, 0xe30d28dd, 0x8ed0d5de, 0x18451114, 0x556b2fd8, 0xc3feeb12, 0xae231611, 0x38b6d2db, + 0x347f6b89, 0xa2eaaf43, 0xcf375240, 0x59a2968a, 0x148ca846, 0x82196c8c, 0xefc4918f, 0x79515545, + 0xf657e32b, 0x60c227e1, 0x0d1fdae2, 0x9b8a1e28, 0xd6a420e4, 0x4031e42e, 0x2dec192d, 0xbb79dde7, + 0xb7b064b5, 0x2125a07f, 0x4cf85d7c, 0xda6d99b6, 0x9743a77a, 0x01d663b0, 0x6c0b9eb3, 0xfa9e5a79, + 0xa4654232, 0x32f086f8, 0x5f2d7bfb, 0xc9b8bf31, 0x849681fd, 0x12034537, 0x7fdeb834, 0xe94b7cfe, + 0xe582c5ac, 0x73170166, 0x1ecafc65, 0x885f38af, 0xc5710663, 0x53e4c2a9, 0x3e393faa, 0xa8acfb60, + 0x27aa4d0e, 0xb13f89c4, 0xdce274c7, 0x4a77b00d, 0x07598ec1, 0x91cc4a0b, 0xfc11b708, 0x6a8473c2, + 0x664dca90, 0xf0d80e5a, 0x9d05f359, 0x0b903793, 0x46be095f, 0xd02bcd95, 0xbdf63096, 0x2b63f45c, + 0xeb31d82e, 0x7da41ce4, 0x1079e1e7, 0x86ec252d, 0xcbc21be1, 0x5d57df2b, 0x308a2228, 0xa61fe6e2, + 0xaad65fb0, 0x3c439b7a, 0x519e6679, 0xc70ba2b3, 0x8a259c7f, 0x1cb058b5, 0x716da5b6, 0xe7f8617c, + 0x68fed712, 0xfe6b13d8, 0x93b6eedb, 0x05232a11, 0x480d14dd, 0xde98d017, 0xb3452d14, 0x25d0e9de, + 0x2919508c, 0xbf8c9446, 0xd2516945, 0x44c4ad8f, 0x09ea9343, 0x9f7f5789, 0xf2a2aa8a, 0x64376e40, + 0x3acc760b, 0xac59b2c1, 0xc1844fc2, 0x57118b08, 0x1a3fb5c4, 0x8caa710e, 0xe1778c0d, 0x77e248c7, + 0x7b2bf195, 0xedbe355f, 0x8063c85c, 0x16f60c96, 0x5bd8325a, 0xcd4df690, 0xa0900b93, 0x3605cf59, + 0xb9037937, 0x2f96bdfd, 0x424b40fe, 0xd4de8434, 0x99f0baf8, 0x0f657e32, 0x62b88331, 0xf42d47fb, + 0xf8e4fea9, 0x6e713a63, 0x03acc760, 0x953903aa, 0xd8173d66, 0x4e82f9ac, 0x235f04af, 0xb5cac065, + 0x9ea93439, 0x083cf0f3, 0x65e10df0, 0xf374c93a, 0xbe5af7f6, 0x28cf333c, 0x4512ce3f, 0xd3870af5, + 0xdf4eb3a7, 0x49db776d, 0x24068a6e, 0xb2934ea4, 0xffbd7068, 0x6928b4a2, 0x04f549a1, 0x92608d6b, + 0x1d663b05, 0x8bf3ffcf, 0xe62e02cc, 0x70bbc606, 0x3d95f8ca, 0xab003c00, 0xc6ddc103, 0x504805c9, + 0x5c81bc9b, 0xca147851, 0xa7c98552, 0x315c4198, 0x7c727f54, 0xeae7bb9e, 0x873a469d, 0x11af8257, + 0x4f549a1c, 0xd9c15ed6, 0xb41ca3d5, 0x2289671f, 0x6fa759d3, 0xf9329d19, 0x94ef601a, 0x027aa4d0, + 0x0eb31d82, 0x9826d948, 0xf5fb244b, 0x636ee081, 0x2e40de4d, 0xb8d51a87, 0xd508e784, 0x439d234e, + 0xcc9b9520, 0x5a0e51ea, 0x37d3ace9, 0xa1466823, 0xec6856ef, 0x7afd9225, 0x17206f26, 0x81b5abec, + 0x8d7c12be, 0x1be9d674, 0x76342b77, 0xe0a1efbd, 0xad8fd171, 0x3b1a15bb, 0x56c7e8b8, 0xc0522c72, +}; +BX_STATIC_ASSERT(BX_COUNTOF(s_crcTableKoopman) == 256); + +static const uint32_t* s_crcTable[] = +{ + s_crcTableIeee, + s_crcTableCastagnoli, + s_crcTableKoopman, +}; +BX_STATIC_ASSERT(BX_COUNTOF(s_crcTable) == HashCrc32::Count); + +void HashCrc32::begin(Enum _type) +{ + m_hash = UINT32_MAX; + m_table = s_crcTable[_type]; +} + +void HashCrc32::add(const void* _data, int _len) +{ + const uint8_t* data = (const uint8_t*)_data; + + uint32_t hash = m_hash; + + while (_len--) + { + hash = m_table[(hash ^ (*data++) ) & UINT8_MAX] ^ (hash >> 8); + } + + m_hash = hash; +} + +} // namespace bx diff --git a/3rdparty/bx/src/math.cpp b/3rdparty/bx/src/math.cpp new file mode 100644 index 00000000000..8327570e936 --- /dev/null +++ b/3rdparty/bx/src/math.cpp @@ -0,0 +1,744 @@ +/* + * Copyright 2011-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/math.h> + +#include <math.h> + +namespace bx +{ + const float kPi = 3.1415926535897932384626433832795f; + const float kPi2 = 6.2831853071795864769252867665590f; + const float kInvPi = 1.0f/kPi; + const float kPiHalf = 1.5707963267948966192313216916398f; + const float kSqrt2 = 1.4142135623730950488016887242097f; + const float kInvLogNat2 = 1.4426950408889634073599246810019f; +#if BX_COMPILER_MSVC + const float kHuge = float(HUGE_VAL); +#else + const float kHuge = HUGE_VALF; +#endif // BX_COMPILER_MSVC + + float fabs(float _a) + { + return ::fabsf(_a); + } + + float fsin(float _a) + { + return ::sinf(_a); + } + + float fasin(float _a) + { + return ::asinf(_a); + } + + float fcos(float _a) + { + return ::cosf(_a); + } + + float ftan(float _a) + { + return ::tanf(_a); + } + + float facos(float _a) + { + return ::acosf(_a); + } + + float fatan2(float _y, float _x) + { + return ::atan2f(_y, _x); + } + + float fpow(float _a, float _b) + { + return ::powf(_a, _b); + } + + float flog(float _a) + { + return ::logf(_a); + } + + float fsqrt(float _a) + { + return ::sqrtf(_a); + } + + float ffloor(float _f) + { + return ::floorf(_f); + } + + float fceil(float _f) + { + return ::ceilf(_f); + } + + float fmod(float _a, float _b) + { + return ::fmodf(_a, _b); + } + + void mtxLookAtImpl(float* _result, const float* _eye, const float* _view, const float* _up) + { + float up[3] = { 0.0f, 1.0f, 0.0f }; + if (NULL != _up) + { + up[0] = _up[0]; + up[1] = _up[1]; + up[2] = _up[2]; + } + + float tmp[4]; + vec3Cross(tmp, up, _view); + + float right[4]; + vec3Norm(right, tmp); + + vec3Cross(up, _view, right); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = right[0]; + _result[ 1] = up[0]; + _result[ 2] = _view[0]; + + _result[ 4] = right[1]; + _result[ 5] = up[1]; + _result[ 6] = _view[1]; + + _result[ 8] = right[2]; + _result[ 9] = up[2]; + _result[10] = _view[2]; + + _result[12] = -vec3Dot(right, _eye); + _result[13] = -vec3Dot(up, _eye); + _result[14] = -vec3Dot(_view, _eye); + _result[15] = 1.0f; + } + + void mtxLookAtLh(float* _result, const float* _eye, const float* _at, const float* _up) + { + float tmp[4]; + vec3Sub(tmp, _at, _eye); + + float view[4]; + vec3Norm(view, tmp); + + mtxLookAtImpl(_result, _eye, view, _up); + } + + void mtxLookAtRh(float* _result, const float* _eye, const float* _at, const float* _up) + { + float tmp[4]; + vec3Sub(tmp, _eye, _at); + + float view[4]; + vec3Norm(view, tmp); + + mtxLookAtImpl(_result, _eye, view, _up); + } + + void mtxLookAt(float* _result, const float* _eye, const float* _at, const float* _up) + { + mtxLookAtLh(_result, _eye, _at, _up); + } + + template<Handness::Enum HandnessT> + void mtxProjXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, float _far, bool _oglNdc) + { + const float diff = _far-_near; + const float aa = _oglNdc ? ( _far+_near)/diff : _far/diff; + const float bb = _oglNdc ? (2.0f*_far*_near)/diff : _near*aa; + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = _width; + _result[ 5] = _height; + _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x; + _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y; + _result[10] = (Handness::Right == HandnessT) ? -aa : aa; + _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f; + _result[14] = -bb; + } + + template<Handness::Enum HandnessT> + void mtxProjImpl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) + { + const float invDiffRl = 1.0f/(_rt - _lt); + const float invDiffUd = 1.0f/(_ut - _dt); + const float width = 2.0f*_near * invDiffRl; + const float height = 2.0f*_near * invDiffUd; + const float xx = (_rt + _lt) * invDiffRl; + const float yy = (_ut + _dt) * invDiffUd; + mtxProjXYWH<HandnessT>(_result, xx, yy, width, height, _near, _far, _oglNdc); + } + + template<Handness::Enum HandnessT> + void mtxProjImpl(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) + { + mtxProjImpl<HandnessT>(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _far, _oglNdc); + } + + template<Handness::Enum HandnessT> + void mtxProjImpl(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) + { + const float height = 1.0f/ftan(toRad(_fovy)*0.5f); + const float width = height * 1.0f/_aspect; + mtxProjXYWH<HandnessT>(_result, 0.0f, 0.0f, width, height, _near, _far, _oglNdc); + } + + void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); + } + + void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _fov, _near, _far, _oglNdc); + } + + void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _fovy, _aspect, _near, _far, _oglNdc); + } + + void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); + } + + void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _fov, _near, _far, _oglNdc); + } + + void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Left>(_result, _fovy, _aspect, _near, _far, _oglNdc); + } + + void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _far, _oglNdc); + } + + void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Right>(_result, _fov, _near, _far, _oglNdc); + } + + void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc) + { + mtxProjImpl<Handness::Right>(_result, _fovy, _aspect, _near, _far, _oglNdc); + } + + template<NearFar::Enum NearFarT, Handness::Enum HandnessT> + void mtxProjInfXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, bool _oglNdc) + { + float aa; + float bb; + if (BX_ENABLED(NearFar::Reverse == NearFarT) ) + { + aa = _oglNdc ? -1.0f : 0.0f; + bb = _oglNdc ? -2.0f*_near : -_near; + } + else + { + aa = 1.0f; + bb = _oglNdc ? 2.0f*_near : _near; + } + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = _width; + _result[ 5] = _height; + _result[ 8] = (Handness::Right == HandnessT) ? _x : -_x; + _result[ 9] = (Handness::Right == HandnessT) ? _y : -_y; + _result[10] = (Handness::Right == HandnessT) ? -aa : aa; + _result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f; + _result[14] = -bb; + } + + template<NearFar::Enum NearFarT, Handness::Enum HandnessT> + void mtxProjInfImpl(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + const float invDiffRl = 1.0f/(_rt - _lt); + const float invDiffUd = 1.0f/(_ut - _dt); + const float width = 2.0f*_near * invDiffRl; + const float height = 2.0f*_near * invDiffUd; + const float xx = (_rt + _lt) * invDiffRl; + const float yy = (_ut + _dt) * invDiffUd; + mtxProjInfXYWH<NearFarT,HandnessT>(_result, xx, yy, width, height, _near, _oglNdc); + } + + template<NearFar::Enum NearFarT, Handness::Enum HandnessT> + void mtxProjInfImpl(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFarT,HandnessT>(_result, _fov[0], _fov[1], _fov[2], _fov[3], _near, _oglNdc); + } + + template<NearFar::Enum NearFarT, Handness::Enum HandnessT> + void mtxProjInfImpl(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + const float height = 1.0f/ftan(toRad(_fovy)*0.5f); + const float width = height * 1.0f/_aspect; + mtxProjInfXYWH<NearFarT,HandnessT>(_result, 0.0f, 0.0f, width, height, _near, _oglNdc); + } + + void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _fov, _near, _oglNdc); + } + + void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc); + } + + void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _fov, _near, _oglNdc); + } + + void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc); + } + + void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Right>(_result, _fov, _near, _oglNdc); + } + + void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Default,Handness::Right>(_result, _fovy, _aspect, _near, _oglNdc); + } + + void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Left>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Left>(_result, _fov, _near, _oglNdc); + } + + void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Left>(_result, _fovy, _aspect, _near, _oglNdc); + } + + void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Right>(_result, _ut, _dt, _lt, _rt, _near, _oglNdc); + } + + void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Right>(_result, _fov, _near, _oglNdc); + } + + void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc) + { + mtxProjInfImpl<NearFar::Reverse,Handness::Right>(_result, _fovy, _aspect, _near, _oglNdc); + } + + template<Handness::Enum HandnessT> + void mtxOrthoImpl(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) + { + const float aa = 2.0f/(_right - _left); + const float bb = 2.0f/(_top - _bottom); + const float cc = (_oglNdc ? 2.0f : 1.0f) / (_far - _near); + const float dd = (_left + _right )/(_left - _right); + const float ee = (_top + _bottom)/(_bottom - _top ); + const float ff = _oglNdc + ? (_near + _far)/(_near - _far) + : _near /(_near - _far) + ; + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = aa; + _result[ 5] = bb; + _result[10] = (Handness::Right == HandnessT) ? -cc : cc; + _result[12] = dd + _offset; + _result[13] = ee; + _result[14] = ff; + _result[15] = 1.0f; + } + + void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) + { + mtxOrthoImpl<Handness::Left>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); + } + + void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) + { + mtxOrthoImpl<Handness::Left>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); + } + + void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc) + { + mtxOrthoImpl<Handness::Right>(_result, _left, _right, _bottom, _top, _near, _far, _offset, _oglNdc); + } + + void mtxRotateX(float* _result, float _ax) + { + const float sx = fsin(_ax); + const float cx = fcos(_ax); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = 1.0f; + _result[ 5] = cx; + _result[ 6] = -sx; + _result[ 9] = sx; + _result[10] = cx; + _result[15] = 1.0f; + } + + void mtxRotateY(float* _result, float _ay) + { + const float sy = fsin(_ay); + const float cy = fcos(_ay); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = cy; + _result[ 2] = sy; + _result[ 5] = 1.0f; + _result[ 8] = -sy; + _result[10] = cy; + _result[15] = 1.0f; + } + + void mtxRotateZ(float* _result, float _az) + { + const float sz = fsin(_az); + const float cz = fcos(_az); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = cz; + _result[ 1] = -sz; + _result[ 4] = sz; + _result[ 5] = cz; + _result[10] = 1.0f; + _result[15] = 1.0f; + } + + void mtxRotateXY(float* _result, float _ax, float _ay) + { + const float sx = fsin(_ax); + const float cx = fcos(_ax); + const float sy = fsin(_ay); + const float cy = fcos(_ay); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = cy; + _result[ 2] = sy; + _result[ 4] = sx*sy; + _result[ 5] = cx; + _result[ 6] = -sx*cy; + _result[ 8] = -cx*sy; + _result[ 9] = sx; + _result[10] = cx*cy; + _result[15] = 1.0f; + } + + void mtxRotateXYZ(float* _result, float _ax, float _ay, float _az) + { + const float sx = fsin(_ax); + const float cx = fcos(_ax); + const float sy = fsin(_ay); + const float cy = fcos(_ay); + const float sz = fsin(_az); + const float cz = fcos(_az); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = cy*cz; + _result[ 1] = -cy*sz; + _result[ 2] = sy; + _result[ 4] = cz*sx*sy + cx*sz; + _result[ 5] = cx*cz - sx*sy*sz; + _result[ 6] = -cy*sx; + _result[ 8] = -cx*cz*sy + sx*sz; + _result[ 9] = cz*sx + cx*sy*sz; + _result[10] = cx*cy; + _result[15] = 1.0f; + } + + void mtxRotateZYX(float* _result, float _ax, float _ay, float _az) + { + const float sx = fsin(_ax); + const float cx = fcos(_ax); + const float sy = fsin(_ay); + const float cy = fcos(_ay); + const float sz = fsin(_az); + const float cz = fcos(_az); + + memSet(_result, 0, sizeof(float)*16); + _result[ 0] = cy*cz; + _result[ 1] = cz*sx*sy-cx*sz; + _result[ 2] = cx*cz*sy+sx*sz; + _result[ 4] = cy*sz; + _result[ 5] = cx*cz + sx*sy*sz; + _result[ 6] = -cz*sx + cx*sy*sz; + _result[ 8] = -sy; + _result[ 9] = cy*sx; + _result[10] = cx*cy; + _result[15] = 1.0f; + }; + + void mtxSRT(float* _result, float _sx, float _sy, float _sz, float _ax, float _ay, float _az, float _tx, float _ty, float _tz) + { + const float sx = fsin(_ax); + const float cx = fcos(_ax); + const float sy = fsin(_ay); + const float cy = fcos(_ay); + const float sz = fsin(_az); + const float cz = fcos(_az); + + const float sxsz = sx*sz; + const float cycz = cy*cz; + + _result[ 0] = _sx * (cycz - sxsz*sy); + _result[ 1] = _sx * -cx*sz; + _result[ 2] = _sx * (cz*sy + cy*sxsz); + _result[ 3] = 0.0f; + + _result[ 4] = _sy * (cz*sx*sy + cy*sz); + _result[ 5] = _sy * cx*cz; + _result[ 6] = _sy * (sy*sz -cycz*sx); + _result[ 7] = 0.0f; + + _result[ 8] = _sz * -cx*sy; + _result[ 9] = _sz * sx; + _result[10] = _sz * cx*cy; + _result[11] = 0.0f; + + _result[12] = _tx; + _result[13] = _ty; + _result[14] = _tz; + _result[15] = 1.0f; + } + + void mtx3Inverse(float* _result, const float* _a) + { + float xx = _a[0]; + float xy = _a[1]; + float xz = _a[2]; + float yx = _a[3]; + float yy = _a[4]; + float yz = _a[5]; + float zx = _a[6]; + float zy = _a[7]; + float zz = _a[8]; + + float det = 0.0f; + det += xx * (yy*zz - yz*zy); + det -= xy * (yx*zz - yz*zx); + det += xz * (yx*zy - yy*zx); + + float invDet = 1.0f/det; + + _result[0] = +(yy*zz - yz*zy) * invDet; + _result[1] = -(xy*zz - xz*zy) * invDet; + _result[2] = +(xy*yz - xz*yy) * invDet; + + _result[3] = -(yx*zz - yz*zx) * invDet; + _result[4] = +(xx*zz - xz*zx) * invDet; + _result[5] = -(xx*yz - xz*yx) * invDet; + + _result[6] = +(yx*zy - yy*zx) * invDet; + _result[7] = -(xx*zy - xy*zx) * invDet; + _result[8] = +(xx*yy - xy*yx) * invDet; + } + + void mtxInverse(float* _result, const float* _a) + { + float xx = _a[ 0]; + float xy = _a[ 1]; + float xz = _a[ 2]; + float xw = _a[ 3]; + float yx = _a[ 4]; + float yy = _a[ 5]; + float yz = _a[ 6]; + float yw = _a[ 7]; + float zx = _a[ 8]; + float zy = _a[ 9]; + float zz = _a[10]; + float zw = _a[11]; + float wx = _a[12]; + float wy = _a[13]; + float wz = _a[14]; + float ww = _a[15]; + + float det = 0.0f; + det += xx * (yy*(zz*ww - zw*wz) - yz*(zy*ww - zw*wy) + yw*(zy*wz - zz*wy) ); + det -= xy * (yx*(zz*ww - zw*wz) - yz*(zx*ww - zw*wx) + yw*(zx*wz - zz*wx) ); + det += xz * (yx*(zy*ww - zw*wy) - yy*(zx*ww - zw*wx) + yw*(zx*wy - zy*wx) ); + det -= xw * (yx*(zy*wz - zz*wy) - yy*(zx*wz - zz*wx) + yz*(zx*wy - zy*wx) ); + + float invDet = 1.0f/det; + + _result[ 0] = +(yy*(zz*ww - wz*zw) - yz*(zy*ww - wy*zw) + yw*(zy*wz - wy*zz) ) * invDet; + _result[ 1] = -(xy*(zz*ww - wz*zw) - xz*(zy*ww - wy*zw) + xw*(zy*wz - wy*zz) ) * invDet; + _result[ 2] = +(xy*(yz*ww - wz*yw) - xz*(yy*ww - wy*yw) + xw*(yy*wz - wy*yz) ) * invDet; + _result[ 3] = -(xy*(yz*zw - zz*yw) - xz*(yy*zw - zy*yw) + xw*(yy*zz - zy*yz) ) * invDet; + + _result[ 4] = -(yx*(zz*ww - wz*zw) - yz*(zx*ww - wx*zw) + yw*(zx*wz - wx*zz) ) * invDet; + _result[ 5] = +(xx*(zz*ww - wz*zw) - xz*(zx*ww - wx*zw) + xw*(zx*wz - wx*zz) ) * invDet; + _result[ 6] = -(xx*(yz*ww - wz*yw) - xz*(yx*ww - wx*yw) + xw*(yx*wz - wx*yz) ) * invDet; + _result[ 7] = +(xx*(yz*zw - zz*yw) - xz*(yx*zw - zx*yw) + xw*(yx*zz - zx*yz) ) * invDet; + + _result[ 8] = +(yx*(zy*ww - wy*zw) - yy*(zx*ww - wx*zw) + yw*(zx*wy - wx*zy) ) * invDet; + _result[ 9] = -(xx*(zy*ww - wy*zw) - xy*(zx*ww - wx*zw) + xw*(zx*wy - wx*zy) ) * invDet; + _result[10] = +(xx*(yy*ww - wy*yw) - xy*(yx*ww - wx*yw) + xw*(yx*wy - wx*yy) ) * invDet; + _result[11] = -(xx*(yy*zw - zy*yw) - xy*(yx*zw - zx*yw) + xw*(yx*zy - zx*yy) ) * invDet; + + _result[12] = -(yx*(zy*wz - wy*zz) - yy*(zx*wz - wx*zz) + yz*(zx*wy - wx*zy) ) * invDet; + _result[13] = +(xx*(zy*wz - wy*zz) - xy*(zx*wz - wx*zz) + xz*(zx*wy - wx*zy) ) * invDet; + _result[14] = -(xx*(yy*wz - wy*yz) - xy*(yx*wz - wx*yz) + xz*(yx*wy - wx*yy) ) * invDet; + _result[15] = +(xx*(yy*zz - zy*yz) - xy*(yx*zz - zx*yz) + xz*(yx*zy - zx*yy) ) * invDet; + } + + void calcLinearFit2D(float _result[2], const void* _points, uint32_t _stride, uint32_t _numPoints) + { + float sumX = 0.0f; + float sumY = 0.0f; + float sumXX = 0.0f; + float sumXY = 0.0f; + + const uint8_t* ptr = (const uint8_t*)_points; + for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride) + { + const float* point = (const float*)ptr; + float xx = point[0]; + float yy = point[1]; + sumX += xx; + sumY += yy; + sumXX += xx*xx; + sumXY += xx*yy; + } + + // [ sum(x^2) sum(x) ] [ A ] = [ sum(x*y) ] + // [ sum(x) numPoints ] [ B ] [ sum(y) ] + + float det = (sumXX*_numPoints - sumX*sumX); + float invDet = 1.0f/det; + + _result[0] = (-sumX * sumY + _numPoints * sumXY) * invDet; + _result[1] = (sumXX * sumY - sumX * sumXY) * invDet; + } + + void calcLinearFit3D(float _result[3], const void* _points, uint32_t _stride, uint32_t _numPoints) + { + float sumX = 0.0f; + float sumY = 0.0f; + float sumZ = 0.0f; + float sumXX = 0.0f; + float sumXY = 0.0f; + float sumXZ = 0.0f; + float sumYY = 0.0f; + float sumYZ = 0.0f; + + const uint8_t* ptr = (const uint8_t*)_points; + for (uint32_t ii = 0; ii < _numPoints; ++ii, ptr += _stride) + { + const float* point = (const float*)ptr; + float xx = point[0]; + float yy = point[1]; + float zz = point[2]; + + sumX += xx; + sumY += yy; + sumZ += zz; + sumXX += xx*xx; + sumXY += xx*yy; + sumXZ += xx*zz; + sumYY += yy*yy; + sumYZ += yy*zz; + } + + // [ sum(x^2) sum(x*y) sum(x) ] [ A ] [ sum(x*z) ] + // [ sum(x*y) sum(y^2) sum(y) ] [ B ] = [ sum(y*z) ] + // [ sum(x) sum(y) numPoints ] [ C ] [ sum(z) ] + + float mtx[9] = + { + sumXX, sumXY, sumX, + sumXY, sumYY, sumY, + sumX, sumY, float(_numPoints), + }; + float invMtx[9]; + mtx3Inverse(invMtx, mtx); + + _result[0] = invMtx[0]*sumXZ + invMtx[1]*sumYZ + invMtx[2]*sumZ; + _result[1] = invMtx[3]*sumXZ + invMtx[4]*sumYZ + invMtx[5]*sumZ; + _result[2] = invMtx[6]*sumXZ + invMtx[7]*sumYZ + invMtx[8]*sumZ; + } + + void rgbToHsv(float _hsv[3], const float _rgb[3]) + { + const float rr = _rgb[0]; + const float gg = _rgb[1]; + const float bb = _rgb[2]; + + const float s0 = fstep(bb, gg); + + const float px = flerp(bb, gg, s0); + const float py = flerp(gg, bb, s0); + const float pz = flerp(-1.0f, 0.0f, s0); + const float pw = flerp(2.0f/3.0f, -1.0f/3.0f, s0); + + const float s1 = fstep(px, rr); + + const float qx = flerp(px, rr, s1); + const float qy = py; + const float qz = flerp(pw, pz, s1); + const float qw = flerp(rr, px, s1); + + const float dd = qx - fmin(qw, qy); + const float ee = 1.0e-10f; + + _hsv[0] = fabs(qz + (qw - qy) / (6.0f * dd + ee) ); + _hsv[1] = dd / (qx + ee); + _hsv[2] = qx; + } + + void hsvToRgb(float _rgb[3], const float _hsv[3]) + { + const float hh = _hsv[0]; + const float ss = _hsv[1]; + const float vv = _hsv[2]; + + const float px = fabs(ffract(hh + 1.0f ) * 6.0f - 3.0f); + const float py = fabs(ffract(hh + 2.0f/3.0f) * 6.0f - 3.0f); + const float pz = fabs(ffract(hh + 1.0f/3.0f) * 6.0f - 3.0f); + + _rgb[0] = vv * flerp(1.0f, fsaturate(px - 1.0f), ss); + _rgb[1] = vv * flerp(1.0f, fsaturate(py - 1.0f), ss); + _rgb[2] = vv * flerp(1.0f, fsaturate(pz - 1.0f), ss); + } + +} // namespace bx diff --git a/3rdparty/bx/src/mutex.cpp b/3rdparty/bx/src/mutex.cpp index 988084bbf0b..74e3c14cf28 100644 --- a/3rdparty/bx/src/mutex.cpp +++ b/3rdparty/bx/src/mutex.cpp @@ -3,13 +3,13 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/mutex.h> #if BX_CONFIG_SUPPORTS_THREADING #if BX_PLATFORM_ANDROID \ || BX_PLATFORM_LINUX \ - || BX_PLATFORM_NACL \ || BX_PLATFORM_IOS \ || BX_PLATFORM_OSX \ || BX_PLATFORM_PS4 \ @@ -17,7 +17,6 @@ # include <pthread.h> #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE # include <windows.h> # include <errno.h> @@ -25,7 +24,9 @@ namespace bx { -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT typedef CRITICAL_SECTION pthread_mutex_t; typedef unsigned pthread_mutexattr_t; @@ -69,7 +70,9 @@ namespace bx pthread_mutexattr_t attr; -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT #else pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); diff --git a/3rdparty/bx/src/os.cpp b/3rdparty/bx/src/os.cpp index 0c7e9dc9a8e..d13ae7859c3 100644 --- a/3rdparty/bx/src/os.cpp +++ b/3rdparty/bx/src/os.cpp @@ -3,48 +3,53 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" +#include <bx/string.h> #include <bx/os.h> #include <bx/uint32_t.h> -#include <bx/string.h> #if !BX_PLATFORM_NONE #include <stdio.h> -#include <sys/stat.h> + +#if BX_CRT_MSVC +# include <direct.h> +#else +# include <unistd.h> +#endif // BX_CRT_MSVC #if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT # include <windows.h> # include <psapi.h> -#elif BX_PLATFORM_ANDROID \ +#elif BX_PLATFORM_ANDROID \ || BX_PLATFORM_EMSCRIPTEN \ - || BX_PLATFORM_BSD \ - || BX_PLATFORM_HURD \ - || BX_PLATFORM_IOS \ - || BX_PLATFORM_LINUX \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_OSX \ - || BX_PLATFORM_PS4 \ - || BX_PLATFORM_RPI \ - || BX_PLATFORM_STEAMLINK + || BX_PLATFORM_BSD \ + || BX_PLATFORM_HURD \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_LINUX \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_RPI \ + || BX_PLATFORM_STEAMLINK \ + || BX_PLATFORM_NX # include <sched.h> // sched_yield -# if BX_PLATFORM_BSD \ - || BX_PLATFORM_IOS \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_OSX \ - || BX_PLATFORM_PS4 \ +# if BX_PLATFORM_BSD \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_PS4 \ || BX_PLATFORM_STEAMLINK # include <pthread.h> // mach_port_t # endif // BX_PLATFORM_* # include <time.h> // nanosleep -# if !BX_PLATFORM_PS4 && !BX_PLATFORM_NACL +# if !BX_PLATFORM_PS4 # include <dlfcn.h> // dlopen, dlclose, dlsym -# endif // !BX_PLATFORM_PS4 && !BX_PLATFORM_NACL +# endif // !BX_PLATFORM_PS4 # if BX_PLATFORM_ANDROID # include <malloc.h> // mallinfo -# elif BX_PLATFORM_LINUX \ - || BX_PLATFORM_RPI \ +# elif BX_PLATFORM_LINUX \ + || BX_PLATFORM_RPI \ || BX_PLATFORM_STEAMLINK # include <unistd.h> // syscall # include <sys/syscall.h> @@ -57,25 +62,20 @@ # endif // BX_PLATFORM_ANDROID #endif // BX_PLATFORM_ -#if BX_CRT_MSVC -# include <direct.h> // _getcwd -#else -# include <unistd.h> // getcwd -#endif // BX_CRT_MSVC - namespace bx { void sleep(uint32_t _ms) { -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 +#if BX_PLATFORM_WINDOWS ::Sleep(_ms); -#elif BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#elif BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT BX_UNUSED(_ms); debugOutput("sleep is not implemented"); debugBreak(); #else - timespec req = {(time_t)_ms/1000, (long)((_ms%1000)*1000000)}; - timespec rem = {0, 0}; + timespec req = { (time_t)_ms/1000, (long)( (_ms%1000)*1000000) }; + timespec rem = { 0, 0 }; ::nanosleep(&req, &rem); #endif // BX_PLATFORM_ } @@ -84,9 +84,8 @@ namespace bx { #if BX_PLATFORM_WINDOWS ::SwitchToThread(); -#elif BX_PLATFORM_XBOX360 - ::Sleep(0); -#elif BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#elif BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT debugOutput("yield is not implemented"); debugBreak(); #else ::sched_yield(); @@ -97,20 +96,21 @@ namespace bx { #if BX_PLATFORM_WINDOWS return ::GetCurrentThreadId(); -#elif BX_PLATFORM_LINUX || BX_PLATFORM_RPI || BX_PLATFORM_STEAMLINK +#elif BX_PLATFORM_LINUX \ + || BX_PLATFORM_RPI \ + || BX_PLATFORM_STEAMLINK return (pid_t)::syscall(SYS_gettid); -#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX +#elif BX_PLATFORM_IOS \ + || BX_PLATFORM_OSX return (mach_port_t)::pthread_mach_thread_np(pthread_self() ); -#elif BX_PLATFORM_BSD || BX_PLATFORM_NACL - // Casting __nc_basic_thread_data*... need better way to do this. +#elif BX_PLATFORM_BSD return *(uint32_t*)::pthread_self(); #elif BX_PLATFORM_HURD return (pthread_t)::pthread_self(); #else -//# pragma message "not implemented." debugOutput("getTid is not implemented"); debugBreak(); return 0; -#endif // +#endif // BX_PLATFORM_ } size_t getProcessMemoryUsed() @@ -118,7 +118,8 @@ namespace bx #if BX_PLATFORM_ANDROID struct mallinfo mi = mallinfo(); return mi.uordblks; -#elif BX_PLATFORM_LINUX || BX_PLATFORM_HURD +#elif BX_PLATFORM_LINUX \ + || BX_PLATFORM_HURD FILE* file = fopen("/proc/self/statm", "r"); if (NULL == file) { @@ -142,7 +143,7 @@ namespace bx , (task_info_t)&info , &infoCount ); -# else // MACH_TASK_BASIC_INFO +# else task_basic_info info; mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT; @@ -151,7 +152,7 @@ namespace bx , (task_info_t)&info , &infoCount ); -# endif // MACH_TASK_BASIC_INFO +# endif // defined(MACH_TASK_BASIC_INFO) if (KERN_SUCCESS != result) { return 0; @@ -175,9 +176,8 @@ namespace bx #if BX_PLATFORM_WINDOWS return (void*)::LoadLibraryA(_filePath); #elif BX_PLATFORM_EMSCRIPTEN \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_PS4 \ - || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_filePath); return NULL; @@ -191,9 +191,8 @@ namespace bx #if BX_PLATFORM_WINDOWS ::FreeLibrary( (HMODULE)_handle); #elif BX_PLATFORM_EMSCRIPTEN \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_PS4 \ - || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_handle); #else @@ -206,9 +205,8 @@ namespace bx #if BX_PLATFORM_WINDOWS return (void*)::GetProcAddress( (HMODULE)_handle, _symbol); #elif BX_PLATFORM_EMSCRIPTEN \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_PS4 \ - || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_handle, _symbol); return NULL; @@ -224,7 +222,7 @@ namespace bx bool result = len != 0 && len < *_inOutSize; *_inOutSize = len; return result; -#elif BX_PLATFORM_PS4 \ +#elif BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_name, _out, _inOutSize); @@ -235,12 +233,12 @@ namespace bx bool result = false; if (NULL != ptr) { - len = (uint32_t)strnlen(ptr); + len = (uint32_t)strLen(ptr); result = len != 0 && len < *_inOutSize; if (len < *_inOutSize) { - strlncpy(_out, len, ptr); + strCopy(_out, *_inOutSize, ptr); } } @@ -253,7 +251,7 @@ namespace bx { #if BX_PLATFORM_WINDOWS ::SetEnvironmentVariableA(_name, _value); -#elif BX_PLATFORM_PS4 \ +#elif BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_name, _value); @@ -266,7 +264,7 @@ namespace bx { #if BX_PLATFORM_WINDOWS ::SetEnvironmentVariableA(_name, NULL); -#elif BX_PLATFORM_PS4 \ +#elif BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_name); @@ -277,7 +275,7 @@ namespace bx int chdir(const char* _path) { -#if BX_PLATFORM_PS4 \ +#if BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT BX_UNUSED(_path); @@ -289,114 +287,10 @@ namespace bx #endif // BX_COMPILER_ } - char* pwd(char* _buffer, uint32_t _size) - { -#if BX_PLATFORM_PS4 \ - || BX_PLATFORM_XBOXONE \ - || BX_PLATFORM_WINRT - BX_UNUSED(_buffer, _size); - return NULL; -#elif BX_CRT_MSVC - return ::_getcwd(_buffer, (int)_size); -#else - return ::getcwd(_buffer, _size); -#endif // BX_COMPILER_ - } - - bool getTempPath(char* _out, uint32_t* _inOutSize) - { -#if BX_PLATFORM_WINDOWS - uint32_t len = ::GetTempPathA(*_inOutSize, _out); - bool result = len != 0 && len < *_inOutSize; - *_inOutSize = len; - return result; -#else - static const char* s_tmp[] = - { - "TMPDIR", - "TMP", - "TEMP", - "TEMPDIR", - - NULL - }; - - for (const char** tmp = s_tmp; *tmp != NULL; ++tmp) - { - uint32_t len = *_inOutSize; - *_out = '\0'; - bool result = getenv(*tmp, _out, &len); - - if (result - && len != 0 - && len < *_inOutSize) - { - *_inOutSize = len; - return result; - } - } - - FileInfo fi; - if (stat("/tmp", fi) - && FileInfo::Directory == fi.m_type) - { - strlncpy(_out, *_inOutSize, "/tmp"); - *_inOutSize = 4; - return true; - } - - return false; -#endif // BX_PLATFORM_* - } - - bool stat(const char* _filePath, FileInfo& _fileInfo) - { - _fileInfo.m_size = 0; - _fileInfo.m_type = FileInfo::Count; - -#if BX_COMPILER_MSVC - struct ::_stat64 st; - int32_t result = ::_stat64(_filePath, &st); - - if (0 != result) - { - return false; - } - - if (0 != (st.st_mode & _S_IFREG) ) - { - _fileInfo.m_type = FileInfo::Regular; - } - else if (0 != (st.st_mode & _S_IFDIR) ) - { - _fileInfo.m_type = FileInfo::Directory; - } -#else - struct ::stat st; - int32_t result = ::stat(_filePath, &st); - if (0 != result) - { - return false; - } - - if (0 != (st.st_mode & S_IFREG) ) - { - _fileInfo.m_type = FileInfo::Regular; - } - else if (0 != (st.st_mode & S_IFDIR) ) - { - _fileInfo.m_type = FileInfo::Directory; - } -#endif // BX_COMPILER_MSVC - - _fileInfo.m_size = st.st_size; - - return true; - } - void* exec(const char* const* _argv) { -#if BX_PLATFORM_LINUX || BX_PLATFORM_HURD +#if BX_PLATFORM_LINUX \ + || BX_PLATFORM_HURD pid_t pid = fork(); if (0 == pid) @@ -408,9 +302,9 @@ namespace bx return (void*)uintptr_t(pid); #elif BX_PLATFORM_WINDOWS - STARTUPINFO si; - memSet(&si, 0, sizeof(STARTUPINFO) ); - si.cb = sizeof(STARTUPINFO); + STARTUPINFOA si; + memSet(&si, 0, sizeof(STARTUPINFOA) ); + si.cb = sizeof(STARTUPINFOA); PROCESS_INFORMATION pi; memSet(&pi, 0, sizeof(PROCESS_INFORMATION) ); @@ -418,7 +312,7 @@ namespace bx int32_t total = 0; for (uint32_t ii = 0; NULL != _argv[ii]; ++ii) { - total += (int32_t)strnlen(_argv[ii]) + 1; + total += (int32_t)strLen(_argv[ii]) + 1; } char* temp = (char*)alloca(total); @@ -426,22 +320,22 @@ namespace bx for(uint32_t ii = 0; NULL != _argv[ii]; ++ii) { len += snprintf(&temp[len], bx::uint32_imax(0, total-len) - , "%s " - , _argv[ii] - ); + , "%s " + , _argv[ii] + ); } bool ok = !!CreateProcessA(_argv[0] - , temp - , NULL - , NULL - , false - , 0 - , NULL - , NULL - , &si - , &pi - ); + , temp + , NULL + , NULL + , false + , 0 + , NULL + , NULL + , &si + , &pi + ); if (ok) { return pi.hProcess; diff --git a/3rdparty/bx/src/process.cpp b/3rdparty/bx/src/process.cpp new file mode 100644 index 00000000000..b748260eece --- /dev/null +++ b/3rdparty/bx/src/process.cpp @@ -0,0 +1,169 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/process.h> + +#include <stdio.h> + +#ifndef BX_CONFIG_CRT_PROCESS +# define BX_CONFIG_CRT_PROCESS !(0 \ + || BX_CRT_NONE \ + || BX_PLATFORM_EMSCRIPTEN \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOXONE \ + ) +#endif // BX_CONFIG_CRT_PROCESS + +namespace bx +{ +#if BX_CONFIG_CRT_PROCESS + +#if BX_CRT_MSVC +# define popen _popen +# define pclose _pclose +#endif // BX_CRT_MSVC + + ProcessReader::ProcessReader() + : m_file(NULL) + { + } + + ProcessReader::~ProcessReader() + { + BX_CHECK(NULL == m_file, "Process not closed!"); + } + + bool ProcessReader::open(const FilePath& _filePath, const StringView& _args, Error* _err) + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + if (NULL != m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessReader: File is already open."); + return false; + } + + char tmp[kMaxFilePath*2] = "\""; + strCat(tmp, BX_COUNTOF(tmp), _filePath.get() ); + strCat(tmp, BX_COUNTOF(tmp), "\" "); + strCat(tmp, BX_COUNTOF(tmp), _args); + + m_file = popen(tmp, "r"); + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessReader: Failed to open process."); + return false; + } + + return true; + } + + void ProcessReader::close() + { + BX_CHECK(NULL != m_file, "Process not open!"); + FILE* file = (FILE*)m_file; + m_exitCode = pclose(file); + m_file = NULL; + } + + int32_t ProcessReader::read(void* _data, int32_t _size, Error* _err) + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err); + + FILE* file = (FILE*)m_file; + int32_t size = (int32_t)fread(_data, 1, _size, file); + if (size != _size) + { + if (0 != feof(file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "ProcessReader: EOF."); + } + else if (0 != ferror(file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "ProcessReader: read error."); + } + + return size >= 0 ? size : 0; + } + + return size; + } + + int32_t ProcessReader::getExitCode() const + { + return m_exitCode; + } + + ProcessWriter::ProcessWriter() + : m_file(NULL) + { + } + + ProcessWriter::~ProcessWriter() + { + BX_CHECK(NULL == m_file, "Process not closed!"); + } + + bool ProcessWriter::open(const FilePath& _filePath, const StringView& _args, Error* _err) + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); + + if (NULL != m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessWriter: File is already open."); + return false; + } + + char tmp[kMaxFilePath*2] = "\""; + strCat(tmp, BX_COUNTOF(tmp), _filePath.get() ); + strCat(tmp, BX_COUNTOF(tmp), "\" "); + strCat(tmp, BX_COUNTOF(tmp), _args); + + m_file = popen(tmp, "w"); + if (NULL == m_file) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessWriter: Failed to open process."); + return false; + } + + return true; + } + + void ProcessWriter::close() + { + BX_CHECK(NULL != m_file, "Process not open!"); + FILE* file = (FILE*)m_file; + m_exitCode = pclose(file); + m_file = NULL; + } + + int32_t ProcessWriter::write(const void* _data, int32_t _size, Error* _err) + { + BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err); + + FILE* file = (FILE*)m_file; + int32_t size = (int32_t)fwrite(_data, 1, _size, file); + if (size != _size) + { + if (0 != ferror(file) ) + { + BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "ProcessWriter: write error."); + } + + return size >= 0 ? size : 0; + } + + return size; + } + + int32_t ProcessWriter::getExitCode() const + { + return m_exitCode; + } +#endif // BX_CONFIG_CRT_PROCESS + +} // namespace bx diff --git a/3rdparty/bx/src/semaphore.cpp b/3rdparty/bx/src/semaphore.cpp index b4369ff0ce6..f321240be18 100644 --- a/3rdparty/bx/src/semaphore.cpp +++ b/3rdparty/bx/src/semaphore.cpp @@ -3,18 +3,21 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/semaphore.h> #if BX_CONFIG_SUPPORTS_THREADING -#if BX_PLATFORM_POSIX +#if BX_PLATFORM_OSX \ +|| BX_PLATFORM_IOS +# include <dispatch/dispatch.h> +#elif BX_PLATFORM_POSIX # include <errno.h> # include <pthread.h> # include <semaphore.h> # include <time.h> #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE # include <windows.h> # include <limits.h> @@ -23,36 +26,87 @@ # endif // BX_PLATFORM_XBOXONE #endif // BX_PLATFORM_ -#ifndef BX_CONFIG_SEMAPHORE_PTHREAD -# define BX_CONFIG_SEMAPHORE_PTHREAD (0 \ - || BX_PLATFORM_OSX \ - || BX_PLATFORM_IOS \ - ) -#endif // BX_CONFIG_SEMAPHORE_PTHREAD - namespace bx { struct SemaphoreInternal { -#if BX_PLATFORM_POSIX -# if BX_CONFIG_SEMAPHORE_PTHREAD +#if BX_PLATFORM_OSX \ +|| BX_PLATFORM_IOS + dispatch_semaphore_t m_handle; +#elif BX_PLATFORM_POSIX pthread_mutex_t m_mutex; pthread_cond_t m_cond; int32_t m_count; -# else - sem_t m_handle; -# endif // BX_CONFIG_SEMAPHORE_PTHREAD #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE HANDLE m_handle; #endif // BX_PLATFORM_ }; -#if BX_PLATFORM_POSIX +#if BX_PLATFORM_OSX \ +|| BX_PLATFORM_IOS + + Semaphore::Semaphore() + { + BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); + + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + si->m_handle = dispatch_semaphore_create(0); + BX_CHECK(NULL != si->m_handle, "dispatch_semaphore_create failed."); + } + + Semaphore::~Semaphore() + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + dispatch_release(si->m_handle); + } + + void Semaphore::post(uint32_t _count) + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + for (uint32_t ii = 0; ii < _count; ++ii) + { + dispatch_semaphore_signal(si->m_handle); + } + } + + bool Semaphore::wait(int32_t _msecs) + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + dispatch_time_t dt = 0 > _msecs + ? DISPATCH_TIME_FOREVER + : dispatch_time(DISPATCH_TIME_NOW, _msecs*1000000) + ; + return !dispatch_semaphore_wait(si->m_handle, dt); + } + +#elif BX_PLATFORM_POSIX + + uint64_t toNs(const timespec& _ts) + { + return _ts.tv_sec*UINT64_C(1000000000) + _ts.tv_nsec; + } + + void toTimespecNs(timespec& _ts, uint64_t _nsecs) + { + _ts.tv_sec = _nsecs/UINT64_C(1000000000); + _ts.tv_nsec = _nsecs%UINT64_C(1000000000); + } + + void toTimespecMs(timespec& _ts, int32_t _msecs) + { + toTimespecNs(_ts, _msecs*1000000); + } + + void add(timespec& _ts, int32_t _msecs) + { + uint64_t ns = toNs(_ts); + toTimespecNs(_ts, ns + _msecs*1000000); + } -# if BX_CONFIG_SEMAPHORE_PTHREAD Semaphore::Semaphore() { BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); @@ -113,15 +167,6 @@ namespace bx int result = pthread_mutex_lock(&si->m_mutex); BX_CHECK(0 == result, "pthread_mutex_lock %d", result); -# if BX_PLATFORM_NACL || BX_PLATFORM_OSX - BX_UNUSED(_msecs); - BX_CHECK(-1 == _msecs, "NaCl and OSX don't support pthread_cond_timedwait at this moment."); - while (0 == result - && 0 >= si->m_count) - { - result = pthread_cond_wait(&si->m_cond, &si->m_mutex); - } -# elif BX_PLATFORM_IOS if (-1 == _msecs) { while (0 == result @@ -133,27 +178,16 @@ namespace bx else { timespec ts; - ts.tv_sec = _msecs/1000; - ts.tv_nsec = (_msecs%1000)*1000; + clock_gettime(CLOCK_REALTIME, &ts); + add(ts, _msecs); while (0 == result && 0 >= si->m_count) { - result = pthread_cond_timedwait_relative_np(&si->m_cond, &si->m_mutex, &ts); + result = pthread_cond_timedwait(&si->m_cond, &si->m_mutex, &ts); } } -# else - timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += _msecs/1000; - ts.tv_nsec += (_msecs%1000)*1000; - - while (0 == result - && 0 >= si->m_count) - { - result = pthread_cond_timedwait(&si->m_cond, &si->m_mutex, &ts); - } -# endif // BX_PLATFORM_ + bool ok = 0 == result; if (ok) @@ -169,80 +203,16 @@ namespace bx return ok; } -# else - - Semaphore::Semaphore() - { - BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); - - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - - int32_t result = sem_init(&si->m_handle, 0, 0); - BX_CHECK(0 == result, "sem_init failed. errno %d", errno); - BX_UNUSED(result); - } - - Semaphore::~Semaphore() - { - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - - int32_t result = sem_destroy(&si->m_handle); - BX_CHECK(0 == result, "sem_destroy failed. errno %d", errno); - BX_UNUSED(result); - } - - void Semaphore::post(uint32_t _count) - { - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - - int32_t result; - for (uint32_t ii = 0; ii < _count; ++ii) - { - result = sem_post(&si->m_handle); - BX_CHECK(0 == result, "sem_post failed. errno %d", errno); - } - BX_UNUSED(result); - } - - bool Semaphore::wait(int32_t _msecs) - { - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - -# if BX_PLATFORM_NACL || BX_PLATFORM_OSX - BX_CHECK(-1 == _msecs, "NaCl and OSX don't support sem_timedwait at this moment."); BX_UNUSED(_msecs); - return 0 == sem_wait(&si->m_handle); -# else - if (0 > _msecs) - { - int32_t result; - do - { - result = sem_wait(&si->m_handle); - } // keep waiting when interrupted by a signal handler... - while (-1 == result && EINTR == errno); - BX_CHECK(0 == result, "sem_wait failed. errno %d", errno); - return 0 == result; - } - - timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += _msecs/1000; - ts.tv_nsec += (_msecs%1000)*1000; - return 0 == sem_timedwait(&si->m_handle, &ts); -# endif // BX_PLATFORM_ - } -# endif // BX_CONFIG_SEMAPHORE_PTHREAD - #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE Semaphore::Semaphore() { SemaphoreInternal* si = (SemaphoreInternal*)m_internal; -#if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINRT \ +|| BX_PLATFORM_XBOXONE si->m_handle = CreateSemaphoreExW(NULL, 0, LONG_MAX, NULL, 0, SEMAPHORE_ALL_ACCESS); #else si->m_handle = CreateSemaphoreA(NULL, 0, LONG_MAX, NULL); @@ -269,7 +239,8 @@ namespace bx SemaphoreInternal* si = (SemaphoreInternal*)m_internal; DWORD milliseconds = (0 > _msecs) ? INFINITE : _msecs; -#if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINRT \ +|| BX_PLATFORM_XBOXONE return WAIT_OBJECT_0 == WaitForSingleObjectEx(si->m_handle, milliseconds, FALSE); #else return WAIT_OBJECT_0 == WaitForSingleObject(si->m_handle, milliseconds); diff --git a/3rdparty/bx/src/settings.cpp b/3rdparty/bx/src/settings.cpp new file mode 100644 index 00000000000..52b8d606c2c --- /dev/null +++ b/3rdparty/bx/src/settings.cpp @@ -0,0 +1,214 @@ +/* + * Copyright 2011-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/settings.h> + +namespace +{ +#define INI_MALLOC(_ctx, _size) (BX_ALLOC(reinterpret_cast<bx::AllocatorI*>(_ctx), _size) ) +#define INI_FREE(_ctx, _ptr) (BX_FREE(reinterpret_cast<bx::AllocatorI*>(_ctx), _ptr) ) +#define INI_MEMCPY(_dst, _src, _count) (bx::memCopy(_dst, _src, _count) ) +#define INI_STRLEN(_str) (bx::strLen(_str) ) +#define INI_STRNICMP(_s1, _s2, _len) (bx::strCmpI(_s1, _s2, _len) ) + +#define INI_IMPLEMENTATION + +BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wunused-function"); + +BX_PRAGMA_DIAGNOSTIC_PUSH(); +BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wsign-compare"); +#include <ini/ini.h> +BX_PRAGMA_DIAGNOSTIC_POP(); +} + +namespace bx +{ + +Settings::Settings(AllocatorI* _allocator, const void* _data, uint32_t _len) + : m_allocator(_allocator) + , m_ini(NULL) +{ + load(_data, _len); +} + +#define INI_T(_ptr) reinterpret_cast<ini_t*>(_ptr) + +Settings::~Settings() +{ + ini_destroy(INI_T(m_ini) ); +} + +void Settings::clear() +{ + load(NULL, 0); +} + +void Settings::load(const void* _data, uint32_t _len) +{ + if (NULL != m_ini) + { + ini_destroy(INI_T(m_ini) ); + } + + if (NULL == _data) + { + m_ini = ini_create(m_allocator); + } + else + { + BX_UNUSED(_len); + m_ini = ini_load( (const char*)_data, m_allocator); + } +} + +const char* Settings::get(const StringView& _name) const +{ + ini_t* ini = INI_T(m_ini); + + FilePath uri(_name); + const StringView path(strTrim(uri.getPath(), "/") ); + const StringView& fileName(uri.getFileName() ); + int32_t section = INI_GLOBAL_SECTION; + + if (!path.isEmpty() ) + { + section = ini_find_section(ini, path.getPtr(), path.getLength() ); + if (INI_NOT_FOUND == section) + { + section = INI_GLOBAL_SECTION; + } + } + + int32_t property = ini_find_property(ini, section, fileName.getPtr(), fileName.getLength() ); + if (INI_NOT_FOUND == property) + { + return NULL; + } + + return ini_property_value(ini, section, property); +} + +void Settings::set(const StringView& _name, const StringView& _value) +{ + ini_t* ini = INI_T(m_ini); + + FilePath uri(_name); + const StringView path(strTrim(uri.getPath(), "/") ); + const StringView& fileName(uri.getFileName() ); + + int32_t section = INI_GLOBAL_SECTION; + + if (!path.isEmpty() ) + { + section = ini_find_section(ini, path.getPtr(), path.getLength() ); + if (INI_NOT_FOUND == section) + { + section = ini_section_add(ini, path.getPtr(), path.getLength() ); + } + } + + int32_t property = ini_find_property(ini, section, fileName.getPtr(), fileName.getLength() ); + if (INI_NOT_FOUND == property) + { + ini_property_add( + ini + , section + , fileName.getPtr() + , fileName.getLength() + , _value.getPtr() + , _value.getLength() + ); + } + else + { + ini_property_value_set( + ini + , section + , property + , _value.getPtr() + , _value.getLength() + ); + } +} + +void Settings::remove(const StringView& _name) const +{ + ini_t* ini = INI_T(m_ini); + + FilePath uri(_name); + const StringView path = strTrim(uri.getPath(), "/"); + const StringView& fileName = uri.getFileName(); + + int32_t section = INI_GLOBAL_SECTION; + + if (!path.isEmpty() ) + { + section = ini_find_section(ini, path.getPtr(), path.getLength() ); + if (INI_NOT_FOUND == section) + { + section = INI_GLOBAL_SECTION; + } + } + + int32_t property = ini_find_property(ini, section, fileName.getPtr(), fileName.getLength() ); + if (INI_NOT_FOUND == property) + { + return; + } + + ini_property_remove(ini, section, property); + + if (INI_GLOBAL_SECTION != section + && 0 == ini_property_count(ini, section) ) + { + ini_section_remove(ini, section); + } +} + +int32_t Settings::read(ReaderSeekerI* _reader, Error* _err) +{ + int32_t size = int32_t(getRemain(_reader) ); + + void* data = BX_ALLOC(m_allocator, size); + + int32_t total = bx::read(_reader, data, size, _err); + load(data, size); + + BX_FREE(m_allocator, data); + + return total; +} + +int32_t Settings::write(WriterI* _writer, Error* _err) const +{ + ini_t* ini = INI_T(m_ini); + + int32_t size = ini_save(ini, NULL, 0); + void* data = BX_ALLOC(m_allocator, size); + + ini_save(ini, (char*)data, size); + int32_t total = bx::write(_writer, data, size-1, _err); + + BX_FREE(m_allocator, data); + + return total; +} + +#undef INI_T + +int32_t read(ReaderSeekerI* _reader, Settings& _settings, Error* _err) +{ + BX_ERROR_SCOPE(_err); + return _settings.read(_reader, _err); +} + +int32_t write(WriterI* _writer, const Settings& _settings, Error* _err) +{ + BX_ERROR_SCOPE(_err); + return _settings.write(_writer, _err); +} + +} // namespace bx diff --git a/3rdparty/bx/src/sort.cpp b/3rdparty/bx/src/sort.cpp index 3b7485fe7fe..3dc1069f56e 100644 --- a/3rdparty/bx/src/sort.cpp +++ b/3rdparty/bx/src/sort.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/sort.h> namespace bx diff --git a/3rdparty/bx/src/string.cpp b/3rdparty/bx/src/string.cpp index dbb59e5090a..5fe272548d0 100644 --- a/3rdparty/bx/src/string.cpp +++ b/3rdparty/bx/src/string.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/allocator.h> #include <bx/hash.h> #include <bx/readerwriter.h> @@ -10,10 +11,16 @@ #if !BX_CRT_NONE # include <stdio.h> // vsnprintf, vsnwprintf +# include <wchar.h> // vswprintf #endif // !BX_CRT_NONE namespace bx { + inline bool isInRange(char _ch, char _from, char _to) + { + return unsigned(_ch - _from) <= unsigned(_to-_from); + } + bool isSpace(char _ch) { return ' ' == _ch @@ -27,12 +34,12 @@ namespace bx bool isUpper(char _ch) { - return _ch >= 'A' && _ch <= 'Z'; + return isInRange(_ch, 'A', 'Z'); } bool isLower(char _ch) { - return _ch >= 'a' && _ch <= 'z'; + return isInRange(_ch, 'a', 'z'); } bool isAlpha(char _ch) @@ -42,7 +49,7 @@ namespace bx bool isNumeric(char _ch) { - return _ch >= '0' && _ch <= '9'; + return isInRange(_ch, '0', '9'); } bool isAlphaNum(char _ch) @@ -52,7 +59,60 @@ namespace bx bool isPrint(char _ch) { - return isAlphaNum(_ch) || isSpace(_ch); + return isInRange(_ch, ' ', '~'); + } + + typedef bool (*CharTestFn)(char _ch); + + template<CharTestFn fn> + inline bool isCharTest(const StringView& _str) + { + bool result = true; + + for (const char* ptr = _str.getPtr(), *term = _str.getTerm() + ; ptr != term && result + ; ++ptr + ) + { + result &= fn(*ptr); + } + + return result; + } + + bool isSpace(const StringView& _str) + { + return isCharTest<isSpace>(_str); + } + + bool isUpper(const StringView& _str) + { + return isCharTest<isUpper>(_str); + } + + bool isLower(const StringView& _str) + { + return isCharTest<isLower>(_str); + } + + bool isAlpha(const StringView& _str) + { + return isCharTest<isAlpha>(_str); + } + + bool isNumeric(const StringView& _str) + { + return isCharTest<isNumeric>(_str); + } + + bool isAlphaNum(const StringView& _str) + { + return isCharTest<isAlphaNum>(_str); + } + + bool isPrint(const StringView& _str) + { + return isCharTest<isPrint>(_str); } char toLower(char _ch) @@ -70,7 +130,7 @@ namespace bx void toLower(char* _inOutStr, int32_t _max) { - const int32_t len = strnlen(_inOutStr, _max); + const int32_t len = strLen(_inOutStr, _max); toLowerUnsafe(_inOutStr, len); } @@ -89,16 +149,10 @@ namespace bx void toUpper(char* _inOutStr, int32_t _max) { - const int32_t len = strnlen(_inOutStr, _max); + const int32_t len = strLen(_inOutStr, _max); toUpperUnsafe(_inOutStr, len); } - bool toBool(const char* _str) - { - char ch = toLower(_str[0]); - return ch == 't' || ch == '1'; - } - typedef char (*CharFn)(char _ch); inline char toNoop(char _ch) @@ -107,11 +161,13 @@ namespace bx } template<CharFn fn> - int32_t strCmp(const char* _lhs, const char* _rhs, int32_t _max) + inline int32_t strCmp(const char* _lhs, int32_t _lhsMax, const char* _rhs, int32_t _rhsMax) { + int32_t max = min(_lhsMax, _rhsMax); + for ( - ; 0 < _max && fn(*_lhs) == fn(*_rhs) - ; ++_lhs, ++_rhs, --_max + ; 0 < max && fn(*_lhs) == fn(*_rhs) + ; ++_lhs, ++_rhs, --max ) { if (*_lhs == '\0' @@ -121,20 +177,105 @@ namespace bx } } - return 0 == _max ? 0 : fn(*_lhs) - fn(*_rhs); + return 0 == max && _lhsMax == _rhsMax ? 0 : fn(*_lhs) - fn(*_rhs); } - int32_t strncmp(const char* _lhs, const char* _rhs, int32_t _max) + int32_t strCmp(const StringView& _lhs, const StringView& _rhs, int32_t _max) { - return strCmp<toNoop>(_lhs, _rhs, _max); + return strCmp<toNoop>( + _lhs.getPtr() + , min(_lhs.getLength(), _max) + , _rhs.getPtr() + , min(_rhs.getLength(), _max) + ); } - int32_t strincmp(const char* _lhs, const char* _rhs, int32_t _max) + int32_t strCmpI(const StringView& _lhs, const StringView& _rhs, int32_t _max) { - return strCmp<toLower>(_lhs, _rhs, _max); + return strCmp<toLower>( + _lhs.getPtr() + , min(_lhs.getLength(), _max) + , _rhs.getPtr() + , min(_rhs.getLength(), _max) + ); } - int32_t strnlen(const char* _str, int32_t _max) + inline int32_t strCmpV(const char* _lhs, int32_t _lhsMax, const char* _rhs, int32_t _rhsMax) + { + int32_t max = min(_lhsMax, _rhsMax); + int32_t ii = 0; + int32_t idx = 0; + bool zero = true; + + for ( + ; 0 < max && _lhs[ii] == _rhs[ii] + ; ++ii, --max + ) + { + const uint8_t ch = _lhs[ii]; + if ('\0' == ch + || '\0' == _rhs[ii]) + { + break; + } + + if (!isNumeric(ch) ) + { + idx = ii+1; + zero = true; + } + else if ('0' != ch) + { + zero = false; + } + } + + if (0 == max) + { + return _lhsMax == _rhsMax ? 0 : _lhs[ii] - _rhs[ii]; + } + + if ('0' != _lhs[idx] + && '0' != _rhs[idx]) + { + int32_t jj = 0; + for (jj = ii + ; 0 < max && isNumeric(_lhs[jj]) + ; ++jj, --max + ) + { + if (!isNumeric(_rhs[jj]) ) + { + return 1; + } + } + + if (isNumeric(_rhs[jj])) + { + return -1; + } + } + else if (zero + && idx < ii + && (isNumeric(_lhs[ii]) || isNumeric(_rhs[ii]) ) ) + { + return (_lhs[ii] - '0') - (_rhs[ii] - '0'); + } + + return 0 == max && _lhsMax == _rhsMax ? 0 : _lhs[ii] - _rhs[ii]; + } + + int32_t strCmpV(const StringView& _lhs, const StringView& _rhs, int32_t _max) + { + return strCmpV( + _lhs.getPtr() + , min(_lhs.getLength(), _max) + , _rhs.getPtr() + , min(_rhs.getLength(), _max) + ); + } + + int32_t strLen(const char* _str, int32_t _max) { if (NULL == _str) { @@ -146,13 +287,18 @@ namespace bx return int32_t(ptr - _str); } - int32_t strlncpy(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) + int32_t strLen(const StringView& _str, int32_t _max) + { + return strLen(_str.getPtr(), min(_str.getLength(), _max) ); + } + + inline int32_t strCopy(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) { BX_CHECK(NULL != _dst, "_dst can't be NULL!"); BX_CHECK(NULL != _src, "_src can't be NULL!"); BX_CHECK(0 < _dstSize, "_dstSize can't be 0!"); - const int32_t len = strnlen(_src, _num); + const int32_t len = strLen(_src, _num); const int32_t max = _dstSize-1; const int32_t num = (len < max ? len : max); memCopy(_dst, _src, num); @@ -161,20 +307,30 @@ namespace bx return num; } - int32_t strlncat(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) + int32_t strCopy(char* _dst, int32_t _dstSize, const StringView& _str, int32_t _num) + { + return strCopy(_dst, _dstSize, _str.getPtr(), min(_str.getLength(), _num) ); + } + + inline int32_t strCat(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) { BX_CHECK(NULL != _dst, "_dst can't be NULL!"); BX_CHECK(NULL != _src, "_src can't be NULL!"); BX_CHECK(0 < _dstSize, "_dstSize can't be 0!"); const int32_t max = _dstSize; - const int32_t len = strnlen(_dst, max); - return strlncpy(&_dst[len], max-len, _src, _num); + const int32_t len = strLen(_dst, max); + return strCopy(&_dst[len], max-len, _src, _num); + } + + int32_t strCat(char* _dst, int32_t _dstSize, const StringView& _str, int32_t _num) + { + return strCat(_dst, _dstSize, _str.getPtr(), min(_str.getLength(), _num) ); } - const char* strnchr(const char* _str, char _ch, int32_t _max) + inline const char* strFindUnsafe(const char* _str, int32_t _len, char _ch) { - for (int32_t ii = 0, len = strnlen(_str, _max); ii < len; ++ii) + for (int32_t ii = 0; ii < _len; ++ii) { if (_str[ii] == _ch) { @@ -185,9 +341,19 @@ namespace bx return NULL; } - const char* strnrchr(const char* _str, char _ch, int32_t _max) + inline const char* strFind(const char* _str, int32_t _max, char _ch) { - for (int32_t ii = strnlen(_str, _max); 0 < ii; --ii) + return strFindUnsafe(_str, strLen(_str, _max), _ch); + } + + const char* strFind(const StringView& _str, char _ch) + { + return strFind(_str.getPtr(), _str.getLength(), _ch); + } + + inline const char* strRFindUnsafe(const char* _str, int32_t _len, char _ch) + { + for (int32_t ii = _len; 0 <= ii; --ii) { if (_str[ii] == _ch) { @@ -198,13 +364,23 @@ namespace bx return NULL; } + inline const char* strRFind(const char* _str, int32_t _max, char _ch) + { + return strRFindUnsafe(_str, strLen(_str, _max), _ch); + } + + const char* strRFind(const StringView& _str, char _ch) + { + return strRFind(_str.getPtr(), _str.getLength(), _ch); + } + template<CharFn fn> - static const char* strStr(const char* _str, int32_t _strMax, const char* _find, int32_t _findMax) + inline const char* strFind(const char* _str, int32_t _strMax, const char* _find, int32_t _findMax) { const char* ptr = _str; - int32_t stringLen = strnlen(_str, _strMax); - const int32_t findLen = strnlen(_find, _findMax); + int32_t stringLen = strLen(_str, _strMax); + const int32_t findLen = strLen(_find, _findMax); for (; stringLen >= findLen; ++ptr, --stringLen) { @@ -239,27 +415,81 @@ namespace bx return NULL; } - const char* strnstr(const char* _str, const char* _find, int32_t _max) + const char* strFind(const StringView& _str, const StringView& _find, int32_t _num) + { + return strFind<toNoop>( + _str.getPtr() + , _str.getLength() + , _find.getPtr() + , min(_find.getLength(), _num) + ); + } + + const char* strFindI(const StringView& _str, const StringView& _find, int32_t _num) + { + return strFind<toLower>( + _str.getPtr() + , _str.getLength() + , _find.getPtr() + , min(_find.getLength(), _num) + ); + } + + StringView strLTrim(const StringView& _str, const StringView& _chars) { - return strStr<toNoop>(_str, _max, _find, INT32_MAX); + const char* ptr = _str.getPtr(); + const char* chars = _chars.getPtr(); + const uint32_t charsLen = _chars.getLength(); + + for (uint32_t ii = 0, len = _str.getLength(); ii < len; ++ii) + { + if (NULL == strFindUnsafe(chars, charsLen, ptr[ii]) ) + { + return StringView(ptr + ii, len-ii); + } + } + + return StringView(); } - const char* stristr(const char* _str, const char* _find, int32_t _max) + StringView strRTrim(const StringView& _str, const StringView& _chars) { - return strStr<toLower>(_str, _max, _find, INT32_MAX); + if (_str.isEmpty() ) + { + return StringView(); + } + + const char* ptr = _str.getPtr(); + const char* chars = _chars.getPtr(); + const uint32_t charsLen = _chars.getLength(); + + for (int32_t len = _str.getLength(), ii = len-1; 0 <= ii; --ii) + { + if (NULL == strFindUnsafe(chars, charsLen, ptr[ii]) ) + { + return StringView(ptr, ii+1); + } + } + + return StringView(); + } + + StringView strTrim(const StringView& _str, const StringView& _chars) + { + return strLTrim(strRTrim(_str, _chars), _chars); } const char* strnl(const char* _str) { - for (; '\0' != *_str; _str += strnlen(_str, 1024) ) + for (; '\0' != *_str; _str += strLen(_str, 1024) ) { - const char* eol = strnstr(_str, "\r\n", 1024); + const char* eol = strFind(StringView(_str, 1024), "\r\n"); if (NULL != eol) { return eol + 2; } - eol = strnstr(_str, "\n", 1024); + eol = strFind(StringView(_str, 1024), "\n"); if (NULL != eol) { return eol + 1; @@ -271,15 +501,15 @@ namespace bx const char* streol(const char* _str) { - for (; '\0' != *_str; _str += strnlen(_str, 1024) ) + for (; '\0' != *_str; _str += strLen(_str, 1024) ) { - const char* eol = strnstr(_str, "\r\n", 1024); + const char* eol = strFind(StringView(_str, 1024), "\r\n"); if (NULL != eol) { return eol; } - eol = strnstr(_str, "\n", 1024); + eol = strFind(StringView(_str, 1024), "\n"); if (NULL != eol) { return eol; @@ -348,9 +578,9 @@ namespace bx const char* findIdentifierMatch(const char* _str, const char* _word) { - int32_t len = strnlen(_word); - const char* ptr = strnstr(_str, _word); - for (; NULL != ptr; ptr = strnstr(ptr + len, _word) ) + int32_t len = strLen(_word); + const char* ptr = strFind(_str, _word); + for (; NULL != ptr; ptr = strFind(ptr + len, _word) ) { if (ptr != _str) { @@ -418,7 +648,7 @@ namespace bx static int32_t write(WriterI* _writer, const char* _str, int32_t _len, const Param& _param, Error* _err) { int32_t size = 0; - int32_t len = (int32_t)strnlen(_str, _len); + int32_t len = (int32_t)strLen(_str, _len); int32_t padding = _param.width > len ? _param.width - len : 0; bool sign = _param.sign && len > 1 && _str[0] != '-'; padding = padding > 0 ? padding - sign : 0; @@ -534,7 +764,7 @@ namespace bx toUpperUnsafe(str, len); } - const char* dot = strnchr(str, '.'); + const char* dot = strFind(str, INT32_MAX, '.'); if (NULL != dot) { const int32_t precLen = int32_t( @@ -574,7 +804,7 @@ namespace bx int32_t write(WriterI* _writer, const char* _format, va_list _argList, Error* _err) { - MemoryReader reader(_format, uint32_t(strnlen(_format) ) ); + MemoryReader reader(_format, uint32_t(strLen(_format) ) ); int32_t size = 0; @@ -793,9 +1023,9 @@ namespace bx { va_list argList; va_start(argList, _format); - int32_t size = write(_writer, _format, argList, _err); + int32_t total = write(_writer, _format, argList, _err); va_end(argList); - return size; + return total; } int32_t vsnprintfRef(char* _out, int32_t _max, const char* _format, va_list _argList) @@ -829,8 +1059,11 @@ namespace bx int32_t vsnprintf(char* _out, int32_t _max, const char* _format, va_list _argList) { + va_list argList; + va_copy(argList, _argList); + int32_t total = 0; #if BX_CRT_NONE - return vsnprintfRef(_out, _max, _format, _argList); + total = vsnprintfRef(_out, _max, _format, argList); #elif BX_CRT_MSVC int32_t len = -1; if (NULL != _out) @@ -840,26 +1073,30 @@ namespace bx len = ::vsnprintf_s(_out, _max, size_t(-1), _format, argListCopy); va_end(argListCopy); } - return -1 == len ? ::_vscprintf(_format, _argList) : len; + total = -1 == len ? ::_vscprintf(_format, argList) : len; #else - return ::vsnprintf(_out, _max, _format, _argList); + total = ::vsnprintf(_out, _max, _format, argList); #endif // BX_COMPILER_MSVC + va_end(argList); + return total; } int32_t snprintf(char* _out, int32_t _max, const char* _format, ...) { va_list argList; va_start(argList, _format); - int32_t len = vsnprintf(_out, _max, _format, argList); + int32_t total = vsnprintf(_out, _max, _format, argList); va_end(argList); - return len; + return total; } int32_t vsnwprintf(wchar_t* _out, int32_t _max, const wchar_t* _format, va_list _argList) { + va_list argList; + va_copy(argList, _argList); + int32_t total = 0; #if BX_CRT_NONE - BX_UNUSED(_out, _max, _format, _argList); - return 0; + BX_UNUSED(_out, _max, _format, argList); #elif BX_CRT_MSVC int32_t len = -1; if (NULL != _out) @@ -869,12 +1106,14 @@ namespace bx len = ::_vsnwprintf_s(_out, _max, size_t(-1), _format, argListCopy); va_end(argListCopy); } - return -1 == len ? ::_vscwprintf(_format, _argList) : len; + total = -1 == len ? ::_vscwprintf(_format, _argList) : len; #elif BX_CRT_MINGW - return ::vsnwprintf(_out, _max, _format, _argList); + total = ::vsnwprintf(_out, _max, _format, argList); #else - return ::vswprintf(_out, _max, _format, _argList); + total = ::vswprintf(_out, _max, _format, argList); #endif // BX_COMPILER_MSVC + va_end(argList); + return total; } int32_t swnprintf(wchar_t* _out, int32_t _max, const wchar_t* _format, ...) @@ -886,44 +1125,36 @@ namespace bx return len; } - const char* baseName(const char* _filePath) - { - const char* bs = strnrchr(_filePath, '\\'); - const char* fs = strnrchr(_filePath, '/'); - const char* slash = (bs > fs ? bs : fs); - const char* colon = strnrchr(_filePath, ':'); - const char* basename = slash > colon ? slash : colon; - if (NULL != basename) - { - return basename+1; - } - - return _filePath; - } + static const char s_units[] = { 'B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' }; - void prettify(char* _out, int32_t _count, uint64_t _size) + template<uint32_t Kilo, char KiloCh0, char KiloCh1> + inline int32_t prettify(char* _out, int32_t _count, uint64_t _value) { uint8_t idx = 0; - double size = double(_size); - while (_size != (_size&0x7ff) - && idx < 9) + double value = double(_value); + while (_value != (_value&0x7ff) + && idx < BX_COUNTOF(s_units) ) { - _size >>= 10; - size *= 1.0/1024.0; + _value /= Kilo; + value *= 1.0/double(Kilo); ++idx; } - snprintf(_out, _count, "%0.2f %c%c", size, "BkMGTPEZY"[idx], idx > 0 ? 'B' : '\0'); + return snprintf(_out, _count, "%0.2f %c%c%c", value + , s_units[idx] + , idx > 0 ? KiloCh0 : '\0' + , KiloCh1 + ); } - int32_t strlcpy(char* _dst, const char* _src, int32_t _max) + int32_t prettify(char* _out, int32_t _count, uint64_t _value, Units::Enum _units) { - return strlncpy(_dst, _max, _src); - } + if (Units::Kilo == _units) + { + return prettify<1000, 'B', '\0'>(_out, _count, _value); + } - int32_t strlcat(char* _dst, const char* _src, int32_t _max) - { - return strlncat(_dst, _max, _src); + return prettify<1024, 'i', 'B'>(_out, _count, _value); } } // namespace bx diff --git a/3rdparty/bx/src/thread.cpp b/3rdparty/bx/src/thread.cpp index 70ea4a0ecbe..fe7f3491dc2 100644 --- a/3rdparty/bx/src/thread.cpp +++ b/3rdparty/bx/src/thread.cpp @@ -3,11 +3,11 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/thread.h> #if BX_PLATFORM_ANDROID \ || BX_PLATFORM_LINUX \ - || BX_PLATFORM_NACL \ || BX_PLATFORM_IOS \ || BX_PLATFORM_OSX \ || BX_PLATFORM_PS4 \ @@ -21,7 +21,6 @@ # endif // BX_PLATFORM_ #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE # include <windows.h> # include <limits.h> @@ -37,11 +36,16 @@ using namespace Windows::System::Threading; namespace bx { + static AllocatorI* getAllocator() + { + static DefaultAllocator s_allocator; + return &s_allocator; + } + struct ThreadInternal { #if BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE static DWORD WINAPI threadFunc(LPVOID _arg); HANDLE m_handle; @@ -52,7 +56,9 @@ namespace bx #endif // BX_PLATFORM_ }; -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT DWORD WINAPI ThreadInternal::threadFunc(LPVOID _arg) { Thread* thread = (Thread*)_arg; @@ -76,8 +82,9 @@ namespace bx Thread::Thread() : m_fn(NULL) , m_userData(NULL) + , m_queue(getAllocator() ) , m_stackSize(0) - , m_exitCode(0 /*EXIT_SUCCESS*/) + , m_exitCode(kExitSuccess) , m_running(false) { BX_STATIC_ASSERT(sizeof(ThreadInternal) <= sizeof(m_internal) ); @@ -85,7 +92,6 @@ namespace bx ThreadInternal* ti = (ThreadInternal*)m_internal; #if BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE ti->m_handle = INVALID_HANDLE_VALUE; ti->m_threadId = UINT32_MAX; @@ -112,7 +118,8 @@ namespace bx m_running = true; ThreadInternal* ti = (ThreadInternal*)m_internal; -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE ti->m_handle = ::CreateThread(NULL , m_stackSize , (LPTHREAD_START_ROUTINE)ti->threadFunc @@ -163,7 +170,7 @@ namespace bx { BX_CHECK(m_running, "Not running!"); ThreadInternal* ti = (ThreadInternal*)m_internal; -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 +#if BX_PLATFORM_WINDOWS WaitForSingleObject(ti->m_handle, INFINITE); GetExitCodeThread(ti->m_handle, (DWORD*)&m_exitCode); CloseHandle(ti->m_handle); @@ -244,6 +251,17 @@ namespace bx #endif // BX_PLATFORM_ } + void Thread::push(void* _ptr) + { + m_queue.push(_ptr); + } + + void* Thread::pop() + { + void* ptr = m_queue.pop(); + return ptr; + } + int32_t Thread::entry() { #if BX_PLATFORM_WINDOWS @@ -252,7 +270,8 @@ namespace bx #endif // BX_PLATFORM_WINDOWS m_sem.post(); - return m_fn(m_userData); + int32_t result = m_fn(this, m_userData); + return result; } struct TlsDataInternal diff --git a/3rdparty/bx/src/timer.cpp b/3rdparty/bx/src/timer.cpp index 7f5403749d9..ad3bb1c32cb 100644 --- a/3rdparty/bx/src/timer.cpp +++ b/3rdparty/bx/src/timer.cpp @@ -3,6 +3,7 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/timer.h> #if BX_PLATFORM_ANDROID @@ -19,7 +20,9 @@ namespace bx { int64_t getHPCounter() { -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT LARGE_INTEGER li; // Performance counter value may unexpectedly leap forward // http://support.microsoft.com/kb/274323 @@ -44,7 +47,9 @@ namespace bx int64_t getHPFrequency() { -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT LARGE_INTEGER li; QueryPerformanceFrequency(&li); return li.QuadPart; diff --git a/3rdparty/bx/src/url.cpp b/3rdparty/bx/src/url.cpp new file mode 100644 index 00000000000..1dda39109bd --- /dev/null +++ b/3rdparty/bx/src/url.cpp @@ -0,0 +1,158 @@ +/* + * Copyright 2011-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bnet#license-bsd-2-clause + */ + +#include "bx_p.h" +#include <bx/url.h> + +namespace bx +{ + UrlView::UrlView() + { + } + + void UrlView::clear() + { + for (uint32_t ii = 0; ii < Count; ++ii) + { + m_tokens[ii].clear(); + } + } + + bool UrlView::parse(const StringView& _url) + { + clear(); + + const char* start = _url.getPtr(); + const char* term = _url.getTerm(); + const char* schemeEnd = strFind(StringView(start, term), "://"); + const char* hostStart = NULL != schemeEnd ? schemeEnd+3 : start; + const char* pathStart = strFind(StringView(hostStart, term), '/'); + + if (NULL == schemeEnd + && NULL == pathStart) + { + return false; + } + + if (NULL != schemeEnd + && (NULL == pathStart || pathStart > schemeEnd) ) + { + StringView scheme(start, schemeEnd); + + if (!isAlpha(scheme) ) + { + return false; + } + + m_tokens[Scheme].set(scheme); + } + + if (NULL != pathStart) + { + const char* queryStart = strFind(StringView(pathStart, term), '?'); + const char* fragmentStart = strFind(StringView(pathStart, term), '#'); + + if (NULL != fragmentStart + && fragmentStart < queryStart) + { + return false; + } + + m_tokens[Path].set(pathStart + , NULL != queryStart ? queryStart + : NULL != fragmentStart ? fragmentStart + : term + ); + + if (NULL != queryStart) + { + m_tokens[Query].set(queryStart+1 + , NULL != fragmentStart ? fragmentStart + : term + ); + } + + if (NULL != fragmentStart) + { + m_tokens[Fragment].set(fragmentStart+1, term); + } + + term = pathStart; + } + + const char* userPassEnd = strFind(StringView(hostStart, term), '@'); + const char* userPassStart = NULL != userPassEnd ? hostStart : NULL; + hostStart = NULL != userPassEnd ? userPassEnd+1 : hostStart; + const char* portStart = strFind(StringView(hostStart, term), ':'); + + m_tokens[Host].set(hostStart, NULL != portStart ? portStart : term); + + if (NULL != portStart) + { + m_tokens[Port].set(portStart+1, term); + } + + if (NULL != userPassStart) + { + const char* passStart = strFind(StringView(userPassStart, userPassEnd), ':'); + + m_tokens[UserName].set(userPassStart + , NULL != passStart ? passStart + : userPassEnd + ); + + if (NULL != passStart) + { + m_tokens[Password].set(passStart+1, userPassEnd); + } + } + + return true; + } + + const StringView& UrlView::get(Enum _token) const + { + return m_tokens[_token]; + } + + static char toHex(char _nible) + { + return "0123456789ABCDEF"[_nible&0xf]; + } + + // https://secure.wikimedia.org/wikipedia/en/wiki/URL_encoding + void urlEncode(char* _out, uint32_t _max, const StringView& _str) + { + _max--; // need space for zero terminator + + const char* str = _str.getPtr(); + const char* term = _str.getTerm(); + + uint32_t ii = 0; + for (char ch = *str++ + ; str <= term && ii < _max + ; ch = *str++ + ) + { + if (isAlphaNum(ch) + || ch == '-' + || ch == '_' + || ch == '.' + || ch == '~') + { + _out[ii++] = ch; + } + else if (ii+3 < _max) + { + _out[ii++] = '%'; + _out[ii++] = toHex(ch>>4); + _out[ii++] = toHex(ch); + } + } + + _out[ii] = '\0'; + } + +} // namespace bx |