summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bx/src
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bx/src')
-rw-r--r--3rdparty/bx/src/allocator.cpp75
-rw-r--r--3rdparty/bx/src/amalgamated.cpp11
-rw-r--r--3rdparty/bx/src/bx.cpp1
-rw-r--r--3rdparty/bx/src/bx_p.h44
-rw-r--r--3rdparty/bx/src/commandline.cpp29
-rw-r--r--3rdparty/bx/src/crtimpl.cpp361
-rw-r--r--3rdparty/bx/src/crtnone.cpp33
-rw-r--r--3rdparty/bx/src/debug.cpp46
-rw-r--r--3rdparty/bx/src/dtoa.cpp668
-rw-r--r--3rdparty/bx/src/easing.cpp64
-rw-r--r--3rdparty/bx/src/file.cpp408
-rw-r--r--3rdparty/bx/src/filepath.cpp543
-rw-r--r--3rdparty/bx/src/fpumath.cpp166
-rw-r--r--3rdparty/bx/src/hash.cpp151
-rw-r--r--3rdparty/bx/src/math.cpp744
-rw-r--r--3rdparty/bx/src/mutex.cpp11
-rw-r--r--3rdparty/bx/src/os.cpp256
-rw-r--r--3rdparty/bx/src/process.cpp169
-rw-r--r--3rdparty/bx/src/semaphore.cpp187
-rw-r--r--3rdparty/bx/src/settings.cpp214
-rw-r--r--3rdparty/bx/src/sort.cpp1
-rw-r--r--3rdparty/bx/src/string.cpp407
-rw-r--r--3rdparty/bx/src/thread.cpp37
-rw-r--r--3rdparty/bx/src/timer.cpp9
-rw-r--r--3rdparty/bx/src/url.cpp158
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