diff options
Diffstat (limited to '3rdparty/bx/include')
64 files changed, 1810 insertions, 1127 deletions
diff --git a/3rdparty/bx/include/bx/allocator.h b/3rdparty/bx/include/bx/allocator.h index cfd1475ab52..7a140b0b562 100644 --- a/3rdparty/bx/include/bx/allocator.h +++ b/3rdparty/bx/include/bx/allocator.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/bx.h b/3rdparty/bx/include/bx/bx.h index 7c2d06162aa..2cfc676d795 100644 --- a/3rdparty/bx/include/bx/bx.h +++ b/3rdparty/bx/include/bx/bx.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -73,27 +73,76 @@ namespace bx template<typename Ty> constexpr bool isPowerOf2(Ty _a); + /// Copy memory block. + /// + /// @param _dst Destination pointer. + /// @param _src Source pointer. + /// @param _numBytes Number of bytes to copy. + /// + /// @remark Source and destination memory blocks must not overlap. /// void memCopy(void* _dst, const void* _src, size_t _numBytes); + /// Copy strided memory block. /// - void memCopy(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch, uint32_t _dstPitch); - + /// @param _dst Destination pointer. + /// @param _dstStride Destination stride. + /// @param _src Source pointer. + /// @param _srcStride Source stride. + /// @param _stride Number of bytes per stride to copy. + /// @param _num Number of strides. /// - void gather(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch); - + /// @remark Source and destination memory blocks must not overlap. /// - void scatter(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _dstPitch); + void memCopy( + void* _dst + , uint32_t _dstStride + , const void* _src + , uint32_t _srcStride + , uint32_t _stride + , uint32_t _num + ); /// void memMove(void* _dst, const void* _src, size_t _numBytes); /// + void memMove( + void* _dst + , uint32_t _dstStride + , const void* _src + , uint32_t _srcStride + , uint32_t _stride + , uint32_t _num + ); + + /// void memSet(void* _dst, uint8_t _ch, size_t _numBytes); /// + void memSet(void* _dst, uint32_t _dstStride, uint8_t _ch, uint32_t _stride, uint32_t _num); + + /// int32_t memCmp(const void* _lhs, const void* _rhs, size_t _numBytes); + /// + void gather( + void* _dst + , const void* _src + , uint32_t _srcStride + , uint32_t _stride + , uint32_t _num + ); + + /// + void scatter( + void* _dst + , uint32_t _dstStride + , const void* _src + , uint32_t _stride + , uint32_t _num + ); + } // namespace bx #include "inline/bx.inl" diff --git a/3rdparty/bx/include/bx/commandline.h b/3rdparty/bx/include/bx/commandline.h index dbd2af39427..058b51c5a5a 100644 --- a/3rdparty/bx/include/bx/commandline.h +++ b/3rdparty/bx/include/bx/commandline.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/config.h b/3rdparty/bx/include/bx/config.h index 787859de6cf..247968a04d7 100644 --- a/3rdparty/bx/include/bx/config.h +++ b/3rdparty/bx/include/bx/config.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/cpu.h b/3rdparty/bx/include/bx/cpu.h index a2e81a1a1ca..9cadf408bd0 100644 --- a/3rdparty/bx/include/bx/cpu.h +++ b/3rdparty/bx/include/bx/cpu.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/debug.h b/3rdparty/bx/include/bx/debug.h index 80efaf97c87..b5a9bc0534e 100644 --- a/3rdparty/bx/include/bx/debug.h +++ b/3rdparty/bx/include/bx/debug.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/easing.h b/3rdparty/bx/include/bx/easing.h index 8581b975c9c..034999081cf 100644 --- a/3rdparty/bx/include/bx/easing.h +++ b/3rdparty/bx/include/bx/easing.h @@ -1,5 +1,5 @@ /* - * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * Copyright 2011-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/endian.h b/3rdparty/bx/include/bx/endian.h index 22965b5f31a..f9eeba0ec54 100644 --- a/3rdparty/bx/include/bx/endian.h +++ b/3rdparty/bx/include/bx/endian.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/error.h b/3rdparty/bx/include/bx/error.h index 1eb220e7be0..f1416b64a7b 100644 --- a/3rdparty/bx/include/bx/error.h +++ b/3rdparty/bx/include/bx/error.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/file.h b/3rdparty/bx/include/bx/file.h index 4c0dd415f1b..42c15ba9622 100644 --- a/3rdparty/bx/include/bx/file.h +++ b/3rdparty/bx/include/bx/file.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -11,19 +11,19 @@ namespace bx { - /// + /// Returns standard input reader. ReaderI* getStdIn(); - /// + /// Returns standard output writer. WriterI* getStdOut(); - /// + /// Returns standard error writer. WriterI* getStdErr(); - /// + /// Returns null output writer. WriterI* getNullOut(); - /// + /// File reader. class FileReader : public FileReaderI { public: @@ -49,7 +49,7 @@ namespace bx BX_ALIGN_DECL(16, uint8_t) m_internal[64]; }; - /// + /// File writer. class FileWriter : public FileWriterI { public: @@ -75,23 +75,68 @@ namespace bx BX_ALIGN_DECL(16, uint8_t) m_internal[64]; }; - /// - struct FileInfo + /// File type. + struct FileType { + /// File types: enum Enum { - Regular, - Directory, + File, //!< File. + Dir, //!< Directory. Count }; + }; + + /// File info. + struct FileInfo + { + FilePath filePath; //!< File path. + uint64_t size; //!< File size. + FileType::Enum type; //!< File type. + }; + + /// Directory reader. + class DirectoryReader : public ReaderOpenI, public CloserI, public ReaderI + { + public: + /// + DirectoryReader(); + + /// + virtual ~DirectoryReader(); + + /// + virtual bool open(const FilePath& _filePath, Error* _err) override; + + /// + virtual void close() override; + + /// + virtual int32_t read(void* _data, int32_t _size, Error* _err) override; - uint64_t m_size; - Enum m_type; + private: + BX_ALIGN_DECL(16, uint8_t) m_internal[sizeof(FilePath)+sizeof(FileInfo)+16]; }; + /// FIle stat. + bool stat(FileInfo& _outFileInfo, const FilePath& _filePath); + + /// Creates a directory named `_filePath`. + /// + bool make(const FilePath& _filePath, Error* _err = NULL); + + /// Creates a directory named `_filePath` along with all necessary parents. + /// + bool makeAll(const FilePath& _filePath, Error* _err = NULL); + + /// Removes file or directory. + /// + bool remove(const FilePath& _filePath, Error* _err = NULL); + + /// Removes file or directory recursivelly. /// - bool stat(const FilePath& _filePath, FileInfo& _outFileInfo); + bool removeAll(const FilePath& _filePath, Error* _err = NULL); } // namespace bx diff --git a/3rdparty/bx/include/bx/filepath.h b/3rdparty/bx/include/bx/filepath.h index c71a1695cfb..920c0b4bbe2 100644 --- a/3rdparty/bx/include/bx/filepath.h +++ b/3rdparty/bx/include/bx/filepath.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -79,9 +79,13 @@ namespace bx /// void join(const StringView& _str); - /// Returns C string to file path. + /// Implicitly converts FilePath to StringView. /// - const char* get() const; + operator StringView() const; + + /// Returns zero-terminated C string pointer to file path. + /// + const char* getCPtr() const; /// If path is `/abv/gd/555/333/pod.mac` returns `/abv/gd/555/333/`. /// @@ -111,22 +115,6 @@ namespace bx char m_filePath[kMaxFilePath]; }; - /// Creates a directory named `_filePath`. - /// - bool make(const FilePath& _filePath, Error* _err = NULL); - - /// Creates a directory named `_filePath` along with all necessary parents. - /// - bool makeAll(const FilePath& _filePath, Error* _err = NULL); - - /// Removes file or directory. - /// - bool remove(const FilePath& _filePath, Error* _err = NULL); - - /// Removes file or directory recursivelly. - /// - bool removeAll(const FilePath& _filePath, Error* _err = NULL); - } // namespace bx #endif // BX_FILEPATH_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/float4x4_t.h b/3rdparty/bx/include/bx/float4x4_t.h index 3250d929db3..9ec367f0739 100644 --- a/3rdparty/bx/include/bx/float4x4_t.h +++ b/3rdparty/bx/include/bx/float4x4_t.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/handlealloc.h b/3rdparty/bx/include/bx/handlealloc.h index 21b07ccca63..a4432b9d176 100644 --- a/3rdparty/bx/include/bx/handlealloc.h +++ b/3rdparty/bx/include/bx/handlealloc.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/hash.h b/3rdparty/bx/include/bx/hash.h index 9ced6947c9f..976fa21acb7 100644 --- a/3rdparty/bx/include/bx/hash.h +++ b/3rdparty/bx/include/bx/hash.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/allocator.inl b/3rdparty/bx/include/bx/inline/allocator.inl index 1ff5f647345..ce4ccc92a72 100644 --- a/3rdparty/bx/include/bx/inline/allocator.inl +++ b/3rdparty/bx/include/bx/inline/allocator.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/bx.inl b/3rdparty/bx/include/bx/inline/bx.inl index c17649a5d69..b0083571ac4 100644 --- a/3rdparty/bx/include/bx/inline/bx.inl +++ b/3rdparty/bx/include/bx/inline/bx.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/cpu.inl b/3rdparty/bx/include/bx/inline/cpu.inl index 3ff2a231fd3..b5a83a4f68d 100644 --- a/3rdparty/bx/include/bx/inline/cpu.inl +++ b/3rdparty/bx/include/bx/inline/cpu.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -12,7 +12,9 @@ # include <windows.h> # endif // BX_PLATFORM_WINRT -# include <emmintrin.h> // _mm_fence +# if BX_CPU_X86 +# include <emmintrin.h> // _mm_fence +# endif extern "C" void _ReadBarrier(); # pragma intrinsic(_ReadBarrier) diff --git a/3rdparty/bx/include/bx/inline/easing.inl b/3rdparty/bx/include/bx/inline/easing.inl index 3cdab9a77cb..02bd7d4e225 100644 --- a/3rdparty/bx/include/bx/inline/easing.inl +++ b/3rdparty/bx/include/bx/inline/easing.inl @@ -1,5 +1,5 @@ /* - * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * Copyright 2011-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/endian.inl b/3rdparty/bx/include/bx/inline/endian.inl index 332e2b6102a..c0fd7480c7a 100644 --- a/3rdparty/bx/include/bx/inline/endian.inl +++ b/3rdparty/bx/include/bx/inline/endian.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -46,7 +46,7 @@ namespace bx } template <typename Ty> - inline Ty toLittleEndian(const Ty _in) + inline Ty toLittleEndian(Ty _in) { #if BX_CPU_ENDIAN_BIG return endianSwap(_in); @@ -56,7 +56,7 @@ namespace bx } template <typename Ty> - inline Ty toBigEndian(const Ty _in) + inline Ty toBigEndian(Ty _in) { #if BX_CPU_ENDIAN_LITTLE return endianSwap(_in); @@ -66,7 +66,7 @@ namespace bx } template <typename Ty> - inline Ty toHostEndian(const Ty _in, bool _fromLittleEndian) + inline Ty toHostEndian(Ty _in, bool _fromLittleEndian) { #if BX_CPU_ENDIAN_LITTLE return _fromLittleEndian ? _in : endianSwap(_in); diff --git a/3rdparty/bx/include/bx/inline/error.inl b/3rdparty/bx/include/bx/inline/error.inl index af5c31a1991..badb75633b0 100644 --- a/3rdparty/bx/include/bx/inline/error.inl +++ b/3rdparty/bx/include/bx/inline/error.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/float4x4_t.inl b/3rdparty/bx/include/bx/inline/float4x4_t.inl index 222c111c361..27bf00d5618 100644 --- a/3rdparty/bx/include/bx/inline/float4x4_t.inl +++ b/3rdparty/bx/include/bx/inline/float4x4_t.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/handlealloc.inl b/3rdparty/bx/include/bx/inline/handlealloc.inl index 3bb364b66b3..94b7ebbda4a 100644 --- a/3rdparty/bx/include/bx/inline/handlealloc.inl +++ b/3rdparty/bx/include/bx/inline/handlealloc.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/hash.inl b/3rdparty/bx/include/bx/inline/hash.inl index 18bee143c70..56430e1470b 100644 --- a/3rdparty/bx/include/bx/inline/hash.inl +++ b/3rdparty/bx/include/bx/inline/hash.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/math.inl b/3rdparty/bx/include/bx/inline/math.inl index 29c88797e94..81ce759ec99 100644 --- a/3rdparty/bx/include/bx/inline/math.inl +++ b/3rdparty/bx/include/bx/inline/math.inl @@ -1,5 +1,5 @@ /* - * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * Copyright 2011-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -95,16 +95,32 @@ namespace bx return tmp == UINT64_C(0x7ff0000000000000); } - inline BX_CONST_FUNC float round(float _f) + inline BX_CONSTEXPR_FUNC float floor(float _a) { - return floor(_f + 0.5f); + if (_a < 0.0f) + { + const float fr = fract(-_a); + const float result = -_a - fr; + + return -(0.0f != fr + ? result + 1.0f + : result) + ; + } + + return _a - fract(_a); } - inline BX_CONST_FUNC float ceil(float _a) + inline BX_CONSTEXPR_FUNC float ceil(float _a) { return -floor(-_a); } + inline BX_CONSTEXPR_FUNC float round(float _f) + { + return floor(_f + 0.5f); + } + inline BX_CONSTEXPR_FUNC float lerp(float _a, float _b, float _t) { return _a + (_b - _a) * _t; @@ -261,7 +277,8 @@ namespace bx inline BX_CONSTEXPR_FUNC bool equal(float _a, float _b, float _epsilon) { // Reference(s): - // - https://web.archive.org/web/20181103180318/http://realtimecollisiondetection.net/blog/?p=89 + // - Floating-point tolerances revisited + // https://web.archive.org/web/20181103180318/http://realtimecollisiondetection.net/blog/?p=89 // const float lhs = abs(_a - _b); const float rhs = _epsilon * max(1.0f, abs(_a), abs(_b) ); @@ -331,26 +348,49 @@ namespace bx return _a + angleDiff(_a, _b) * _t; } - inline Vec3 load(const void* _ptr) + template<typename Ty> + inline Ty load(const void* _ptr) { - const float* ptr = reinterpret_cast<const float*>(_ptr); - return - { - ptr[0], - ptr[1], - ptr[2], - }; + Ty result; + memCopy(&result, _ptr, sizeof(Ty) ); + return result; + } + + template<typename Ty> + inline void store(void* _ptr, const Ty& _a) + { + memCopy(_ptr, &_a, sizeof(Ty) ); } - inline void store(void* _ptr, const Vec3& _a) + inline Vec3::Vec3() { - float* ptr = reinterpret_cast<float*>(_ptr); - ptr[0] = _a.x; - ptr[1] = _a.y; - ptr[2] = _a.z; } - inline BX_CONSTEXPR_FUNC Vec3 abs(const Vec3& _a) + constexpr Vec3::Vec3(float _v) + : x(_v) + , y(_v) + , z(_v) + { + } + + constexpr Vec3::Vec3(float _x, float _y, float _z) + : x(_x) + , y(_y) + , z(_z) + { + } + + inline BX_CONSTEXPR_FUNC Vec3 round(const Vec3 _a) + { + return + { + round(_a.x), + round(_a.y), + round(_a.z), + }; + } + + inline BX_CONSTEXPR_FUNC Vec3 abs(const Vec3 _a) { return { @@ -360,7 +400,7 @@ namespace bx }; } - inline BX_CONSTEXPR_FUNC Vec3 neg(const Vec3& _a) + inline BX_CONSTEXPR_FUNC Vec3 neg(const Vec3 _a) { return { @@ -370,7 +410,7 @@ namespace bx }; } - inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, const Vec3& _b) + inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3 _a, const Vec3 _b) { return { @@ -380,7 +420,7 @@ namespace bx }; } - inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, float _b) + inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3 _a, float _b) { return { @@ -390,7 +430,7 @@ namespace bx }; } - inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, const Vec3& _b) + inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3 _a, const Vec3 _b) { return { @@ -400,7 +440,7 @@ namespace bx }; } - inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, float _b) + inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3 _a, float _b) { return { @@ -410,7 +450,7 @@ namespace bx }; } - inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, const Vec3& _b) + inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _a, const Vec3 _b) { return { @@ -420,7 +460,7 @@ namespace bx }; } - inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, float _b) + inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _a, float _b) { return { @@ -430,17 +470,22 @@ namespace bx }; } - inline BX_CONSTEXPR_FUNC Vec3 mad(const Vec3& _a, const Vec3& _b, const Vec3& _c) + inline BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const float _b, const Vec3 _c) + { + return add(mul(_a, _b), _c); + } + + inline BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const Vec3 _b, const Vec3 _c) { return add(mul(_a, _b), _c); } - inline BX_CONSTEXPR_FUNC float dot(const Vec3& _a, const Vec3& _b) + inline BX_CONSTEXPR_FUNC float dot(const Vec3 _a, const Vec3 _b) { return _a.x*_b.x + _a.y*_b.y + _a.z*_b.z; } - inline BX_CONSTEXPR_FUNC Vec3 cross(const Vec3& _a, const Vec3& _b) + inline BX_CONSTEXPR_FUNC Vec3 cross(const Vec3 _a, const Vec3 _b) { return { @@ -450,12 +495,23 @@ namespace bx }; } - inline BX_CONST_FUNC float length(const Vec3& _a) + inline BX_CONST_FUNC float length(const Vec3 _a) { return sqrt(dot(_a, _a) ); } - inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, float _t) + inline BX_CONST_FUNC float distanceSq(const Vec3 _a, const Vec3 _b) + { + const Vec3 ba = sub(_b, _a); + return dot(ba, ba); + } + + inline BX_CONST_FUNC float distance(const Vec3 _a, const Vec3 _b) + { + return length(sub(_b, _a) ); + } + + inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3 _a, const Vec3 _b, float _t) { return { @@ -465,7 +521,7 @@ namespace bx }; } - inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, const Vec3& _t) + inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3 _a, const Vec3 _b, const Vec3 _t) { return { @@ -475,14 +531,14 @@ namespace bx }; } - inline BX_CONST_FUNC Vec3 normalize(const Vec3& _a) + inline BX_CONST_FUNC Vec3 normalize(const Vec3 _a) { const float invLen = 1.0f/length(_a); - const Vec3 result = mul(_a, invLen); + const Vec3 result = mul(_a, invLen); return result; } - inline BX_CONSTEXPR_FUNC Vec3 min(const Vec3& _a, const Vec3& _b) + inline BX_CONSTEXPR_FUNC Vec3 min(const Vec3 _a, const Vec3 _b) { return { @@ -492,7 +548,7 @@ namespace bx }; } - inline BX_CONSTEXPR_FUNC Vec3 max(const Vec3& _a, const Vec3& _b) + inline BX_CONSTEXPR_FUNC Vec3 max(const Vec3 _a, const Vec3 _b) { return { @@ -502,7 +558,7 @@ namespace bx }; } - inline BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3& _a) + inline BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3 _a) { return { @@ -512,7 +568,7 @@ namespace bx }; } - inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n) + inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3 _n) { const float nx = _n.x; const float ny = _n.y; @@ -536,7 +592,7 @@ namespace bx _outB = cross(_n, _outT); } - inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n, float _angle) + inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3 _n, float _angle) { calcTangentFrame(_outT, _outB, _n); @@ -567,292 +623,181 @@ namespace bx return result; } - inline void toLatLong(float* _outU, float* _outV, const Vec3& _dir) + inline void toLatLong(float* _outU, float* _outV, const Vec3 _dir) { const float phi = atan2(_dir.x, _dir.z); const float theta = acos(_dir.y); - *_outU = (bx::kPi + phi)/bx::kPi2; - *_outV = theta*bx::kInvPi; - } - - inline void vec3Add(float* _result, const float* _a, const float* _b) - { - _result[0] = _a[0] + _b[0]; - _result[1] = _a[1] + _b[1]; - _result[2] = _a[2] + _b[2]; - } - - inline void vec3Sub(float* _result, const float* _a, const float* _b) - { - _result[0] = _a[0] - _b[0]; - _result[1] = _a[1] - _b[1]; - _result[2] = _a[2] - _b[2]; - } - - inline void vec3Mul(float* _result, const float* _a, const float* _b) - { - _result[0] = _a[0] * _b[0]; - _result[1] = _a[1] * _b[1]; - _result[2] = _a[2] * _b[2]; - } - - inline void vec3Mul(float* _result, const float* _a, float _b) - { - _result[0] = _a[0] * _b; - _result[1] = _a[1] * _b; - _result[2] = _a[2] * _b; - } - - inline float vec3Dot(const float* _a, const float* _b) - { - return _a[0]*_b[0] + _a[1]*_b[1] + _a[2]*_b[2]; - } - - inline void vec3Cross(float* _result, const float* _a, const float* _b) - { - _result[0] = _a[1]*_b[2] - _a[2]*_b[1]; - _result[1] = _a[2]*_b[0] - _a[0]*_b[2]; - _result[2] = _a[0]*_b[1] - _a[1]*_b[0]; - } - - inline float vec3Length(const float* _a) - { - return sqrt(vec3Dot(_a, _a) ); - } - - inline float vec3Norm(float* _result, const float* _a) - { - const float len = vec3Length(_a); - const float invLen = 1.0f/len; - _result[0] = _a[0] * invLen; - _result[1] = _a[1] * invLen; - _result[2] = _a[2] * invLen; - return len; + *_outU = (kPi + phi)/kPi2; + *_outV = theta*kInvPi; } - inline void vec3TangentFrame(const float* _n, float* _t, float* _b) + inline BX_CONSTEXPR_FUNC Quaternion invert(const Quaternion _a) { - const float nx = _n[0]; - const float ny = _n[1]; - const float nz = _n[2]; - - if (abs(nx) > abs(nz) ) - { - float invLen = 1.0f / sqrt(nx*nx + nz*nz); - _t[0] = -nz * invLen; - _t[1] = 0.0f; - _t[2] = nx * invLen; - } - else + return { - float invLen = 1.0f / sqrt(ny*ny + nz*nz); - _t[0] = 0.0f; - _t[1] = nz * invLen; - _t[2] = -ny * invLen; - } - - vec3Cross(_b, _n, _t); - } - - inline void vec3TangentFrame(const float* _n, float* _t, float* _b, float _angle) - { - vec3TangentFrame(_n, _t, _b); - - const float sa = sin(_angle); - const float ca = cos(_angle); - - _t[0] = -sa * _b[0] + ca * _t[0]; - _t[1] = -sa * _b[1] + ca * _t[1]; - _t[2] = -sa * _b[2] + ca * _t[2]; - - vec3Cross(_b, _n, _t); - } - - inline void vec3FromLatLong(float* _vec, float _u, float _v) - { - const float phi = _u * kPi2; - const float theta = _v * kPi; - - const float st = sin(theta); - const float sp = sin(phi); - const float ct = cos(theta); - const float cp = cos(phi); - - _vec[0] = -st*sp; - _vec[1] = ct; - _vec[2] = -st*cp; + -_a.x, + -_a.y, + -_a.z, + _a.w, + }; } - inline void vec3ToLatLong(float* _outU, float* _outV, const float* _dir) + inline BX_CONSTEXPR_FUNC Vec3 mulXyz(const Quaternion _a, const Quaternion _b) { - const float phi = atan2(_dir[0], _dir[2]); - const float theta = acos(_dir[1]); + const float ax = _a.x; + const float ay = _a.y; + const float az = _a.z; + const float aw = _a.w; - *_outU = (bx::kPi + phi)/bx::kPi2; - *_outV = theta*bx::kInvPi; - } - - inline void quatIdentity(float* _result) - { - _result[0] = 0.0f; - _result[1] = 0.0f; - _result[2] = 0.0f; - _result[3] = 1.0f; - } + const float bx = _b.x; + const float by = _b.y; + const float bz = _b.z; + const float bw = _b.w; - inline void quatMove(float* _result, const float* _a) - { - _result[0] = _a[0]; - _result[1] = _a[1]; - _result[2] = _a[2]; - _result[3] = _a[3]; + return + { + aw * bx + ax * bw + ay * bz - az * by, + aw * by - ax * bz + ay * bw + az * bx, + aw * bz + ax * by - ay * bx + az * bw, + }; } - inline void quatMulXYZ(float* _result, const float* _qa, const float* _qb) + inline BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, const Quaternion _b) { - const float ax = _qa[0]; - const float ay = _qa[1]; - const float az = _qa[2]; - const float aw = _qa[3]; + const float ax = _a.x; + const float ay = _a.y; + const float az = _a.z; + const float aw = _a.w; - const float bx = _qb[0]; - const float by = _qb[1]; - const float bz = _qb[2]; - const float bw = _qb[3]; + const float bx = _b.x; + const float by = _b.y; + const float bz = _b.z; + const float bw = _b.w; - _result[0] = aw * bx + ax * bw + ay * bz - az * by; - _result[1] = aw * by - ax * bz + ay * bw + az * bx; - _result[2] = aw * bz + ax * by - ay * bx + az * bw; + return + { + aw * bx + ax * bw + ay * bz - az * by, + aw * by - ax * bz + ay * bw + az * bx, + aw * bz + ax * by - ay * bx + az * bw, + aw * bw - ax * bx - ay * by - az * bz, + }; } - inline void quatMul(float* _result, const float* _qa, const float* _qb) + inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _v, const Quaternion _q) { - const float ax = _qa[0]; - const float ay = _qa[1]; - const float az = _qa[2]; - const float aw = _qa[3]; - - const float bx = _qb[0]; - const float by = _qb[1]; - const float bz = _qb[2]; - const float bw = _qb[3]; - - _result[0] = aw * bx + ax * bw + ay * bz - az * by; - _result[1] = aw * by - ax * bz + ay * bw + az * bx; - _result[2] = aw * bz + ax * by - ay * bx + az * bw; - _result[3] = aw * bw - ax * bx - ay * by - az * bz; - } + const Quaternion tmp0 = invert(_q); + const Quaternion qv = { _v.x, _v.y, _v.z, 0.0f }; + const Quaternion tmp1 = mul(tmp0, qv); + const Vec3 result = mulXyz(tmp1, _q); - inline void quatInvert(float* _result, const float* _quat) - { - _result[0] = -_quat[0]; - _result[1] = -_quat[1]; - _result[2] = -_quat[2]; - _result[3] = _quat[3]; + return result; } - inline float quatDot(const float* _a, const float* _b) + inline BX_CONSTEXPR_FUNC float dot(const Quaternion _a, const Quaternion _b) { - return _a[0]*_b[0] - + _a[1]*_b[1] - + _a[2]*_b[2] - + _a[3]*_b[3] - ; + return + _a.x * _b.x + + _a.y * _b.y + + _a.z * _b.z + + _a.w * _b.w + ; } - inline void quatNorm(float* _result, const float* _quat) + inline BX_CONSTEXPR_FUNC Quaternion normalize(const Quaternion _a) { - const float norm = quatDot(_quat, _quat); + const float norm = dot(_a, _a); if (0.0f < norm) { const float invNorm = 1.0f / sqrt(norm); - _result[0] = _quat[0] * invNorm; - _result[1] = _quat[1] * invNorm; - _result[2] = _quat[2] * invNorm; - _result[3] = _quat[3] * invNorm; + + return + { + _a.x * invNorm, + _a.y * invNorm, + _a.z * invNorm, + _a.w * invNorm, + }; } - else + + return { - quatIdentity(_result); - } + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }; } - inline void quatToEuler(float* _result, const float* _quat) + inline BX_CONST_FUNC Vec3 toEuler(const Quaternion _a) { - const float x = _quat[0]; - const float y = _quat[1]; - const float z = _quat[2]; - const float w = _quat[3]; + const float xx = _a.x; + const float yy = _a.y; + const float zz = _a.z; + const float ww = _a.w; + const float xsq = square(xx); + const float ysq = square(yy); + const float zsq = square(zz); - const float yy = y * y; - const float zz = z * z; - - const float xx = x * x; - _result[0] = atan2(2.0f * (x * w - y * z), 1.0f - 2.0f * (xx + zz) ); - _result[1] = atan2(2.0f * (y * w + x * z), 1.0f - 2.0f * (yy + zz) ); - _result[2] = asin (2.0f * (x * y + z * w) ); + return + { + atan2(2.0f * (xx * ww - yy * zz), 1.0f - 2.0f * (xsq + zsq) ), + atan2(2.0f * (yy * ww + xx * zz), 1.0f - 2.0f * (ysq + zsq) ), + asin( 2.0f * (xx * yy + zz * ww) ), + }; } - inline void quatRotateAxis(float* _result, const float* _axis, float _angle) + inline BX_CONST_FUNC Quaternion rotateAxis(const Vec3 _axis, float _angle) { const float ha = _angle * 0.5f; - const float ca = cos(ha); const float sa = sin(ha); - _result[0] = _axis[0] * sa; - _result[1] = _axis[1] * sa; - _result[2] = _axis[2] * sa; - _result[3] = ca; + + return + { + _axis.x * sa, + _axis.y * sa, + _axis.z * sa, + cos(ha), + }; } - inline void quatRotateX(float* _result, float _ax) + inline BX_CONST_FUNC Quaternion rotateX(float _ax) { const float hx = _ax * 0.5f; - const float cx = cos(hx); - const float sx = sin(hx); - _result[0] = sx; - _result[1] = 0.0f; - _result[2] = 0.0f; - _result[3] = cx; + + return + { + sin(hx), + 0.0f, + 0.0f, + cos(hx), + }; } - inline void quatRotateY(float* _result, float _ay) + inline BX_CONST_FUNC Quaternion rotateY(float _ay) { const float hy = _ay * 0.5f; - const float cy = cos(hy); - const float sy = sin(hy); - _result[0] = 0.0f; - _result[1] = sy; - _result[2] = 0.0f; - _result[3] = cy; - } - inline void quatRotateZ(float* _result, float _az) - { - const float hz = _az * 0.5f; - const float cz = cos(hz); - const float sz = sin(hz); - _result[0] = 0.0f; - _result[1] = 0.0f; - _result[2] = sz; - _result[3] = cz; + return + { + 0.0f, + sin(hy), + 0.0f, + cos(hy), + }; } - inline void vec3MulQuat(float* _result, const float* _vec, const float* _quat) + inline BX_CONST_FUNC Quaternion rotateZ(float _az) { - float tmp0[4]; - quatInvert(tmp0, _quat); - - float qv[4]; - qv[0] = _vec[0]; - qv[1] = _vec[1]; - qv[2] = _vec[2]; - qv[3] = 0.0f; - - float tmp1[4]; - quatMul(tmp1, tmp0, qv); + const float hz = _az * 0.5f; - quatMulXYZ(_result, tmp1, _quat); + return + { + 0.0f, + 0.0f, + sin(hz), + cos(hz), + }; } inline void mtxIdentity(float* _result) @@ -883,63 +828,63 @@ namespace bx mtxScale(_result, _scale, _scale, _scale); } - inline void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos) + inline void mtxFromNormal(float* _result, const Vec3& _normal, float _scale, const Vec3& _pos) { - float tangent[3]; - float bitangent[3]; - vec3TangentFrame(_normal, tangent, bitangent); + Vec3 tangent; + Vec3 bitangent; + calcTangentFrame(tangent, bitangent, _normal); - vec3Mul(&_result[ 0], bitangent, _scale); - vec3Mul(&_result[ 4], _normal, _scale); - vec3Mul(&_result[ 8], tangent, _scale); + store(&_result[ 0], mul(bitangent, _scale) ); + store(&_result[ 4], mul(_normal, _scale) ); + store(&_result[ 8], mul(tangent, _scale) ); _result[ 3] = 0.0f; _result[ 7] = 0.0f; _result[11] = 0.0f; - _result[12] = _pos[0]; - _result[13] = _pos[1]; - _result[14] = _pos[2]; + _result[12] = _pos.x; + _result[13] = _pos.y; + _result[14] = _pos.z; _result[15] = 1.0f; } - inline void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos, float _angle) + inline void mtxFromNormal(float* _result, const Vec3& _normal, float _scale, const Vec3& _pos, float _angle) { - float tangent[3]; - float bitangent[3]; - vec3TangentFrame(_normal, tangent, bitangent, _angle); + Vec3 tangent; + Vec3 bitangent; + calcTangentFrame(tangent, bitangent, _normal, _angle); - vec3Mul(&_result[ 0], bitangent, _scale); - vec3Mul(&_result[ 4], _normal, _scale); - vec3Mul(&_result[ 8], tangent, _scale); + store(&_result[0], mul(bitangent, _scale) ); + store(&_result[4], mul(_normal, _scale) ); + store(&_result[8], mul(tangent, _scale) ); _result[ 3] = 0.0f; _result[ 7] = 0.0f; _result[11] = 0.0f; - _result[12] = _pos[0]; - _result[13] = _pos[1]; - _result[14] = _pos[2]; + _result[12] = _pos.x; + _result[13] = _pos.y; + _result[14] = _pos.z; _result[15] = 1.0f; } - inline void mtxQuat(float* _result, const float* _quat) + inline void mtxQuat(float* _result, const Quaternion& _quat) { - const float x = _quat[0]; - const float y = _quat[1]; - const float z = _quat[2]; - const float w = _quat[3]; + const float qx = _quat.x; + const float qy = _quat.y; + const float qz = _quat.z; + const float qw = _quat.w; - const float x2 = x + x; - const float y2 = y + y; - const float z2 = z + z; - const float x2x = x2 * x; - const float x2y = x2 * y; - const float x2z = x2 * z; - const float x2w = x2 * w; - const float y2y = y2 * y; - const float y2z = y2 * z; - const float y2w = y2 * w; - const float z2z = z2 * z; - const float z2w = z2 * w; + const float x2 = qx + qx; + const float y2 = qy + qy; + const float z2 = qz + qz; + const float x2x = x2 * qx; + const float x2y = x2 * qy; + const float x2z = x2 * qz; + const float x2w = x2 * qw; + const float y2y = y2 * qy; + const float y2z = y2 * qz; + const float y2w = y2 * qw; + const float z2z = z2 * qz; + const float z2w = z2 * qw; _result[ 0] = 1.0f - (y2y + z2z); _result[ 1] = x2y - z2w; @@ -962,21 +907,21 @@ namespace bx _result[15] = 1.0f; } - inline void mtxQuatTranslation(float* _result, const float* _quat, const float* _translation) + inline void mtxQuatTranslation(float* _result, const Quaternion& _quat, const Vec3& _translation) { mtxQuat(_result, _quat); - _result[12] = -(_result[0]*_translation[0] + _result[4]*_translation[1] + _result[ 8]*_translation[2]); - _result[13] = -(_result[1]*_translation[0] + _result[5]*_translation[1] + _result[ 9]*_translation[2]); - _result[14] = -(_result[2]*_translation[0] + _result[6]*_translation[1] + _result[10]*_translation[2]); + store(&_result[12], neg(mulXyz0(_translation, _result) ) ); } - inline void mtxQuatTranslationHMD(float* _result, const float* _quat, const float* _translation) + inline void mtxQuatTranslationHMD(float* _result, const Quaternion& _quat, const Vec3& _translation) { - float quat[4]; - quat[0] = -_quat[0]; - quat[1] = -_quat[1]; - quat[2] = _quat[2]; - quat[3] = _quat[3]; + const Quaternion quat = + { + -_quat.x, + -_quat.y, + _quat.z, + _quat.w, + }; mtxQuatTranslation(_result, quat, _translation); } @@ -1016,48 +961,6 @@ namespace bx return result; } - inline void vec3MulMtx(float* _result, const float* _vec, const float* _mat) - { - _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12]; - _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13]; - _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14]; - } - - inline void vec3MulMtxXyz0(float* _result, const float* _vec, const float* _mat) - { - _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8]; - _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9]; - _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10]; - } - - inline void vec3MulMtxH(float* _result, const float* _vec, const float* _mat) - { - float xx = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12]; - float yy = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13]; - float zz = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14]; - float ww = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _mat[15]; - float invW = sign(ww)/ww; - _result[0] = xx*invW; - _result[1] = yy*invW; - _result[2] = zz*invW; - } - - inline void vec4Mul(float* _result, const float* _a, const float* _b) - { - _result[0] = _a[0] * _b[0]; - _result[1] = _a[1] * _b[1]; - _result[2] = _a[2] * _b[2]; - _result[3] = _a[3] * _b[3]; - } - - inline void vec4Mul(float* _result, const float* _a, float _b) - { - _result[0] = _a[0] * _b; - _result[1] = _a[1] * _b; - _result[2] = _a[2] * _b; - _result[3] = _a[3] * _b; - } - inline void vec4MulMtx(float* _result, const float* _vec, const float* _mat) { _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _vec[3] * _mat[12]; @@ -1094,75 +997,30 @@ namespace bx _result[15] = _a[15]; } - /// Convert LH to RH projection matrix and vice versa. - inline void mtxProjFlipHandedness(float* _dst, const float* _src) + inline Vec3 calcNormal(const Vec3& _va, const Vec3& _vb, const Vec3& _vc) { - _dst[ 0] = -_src[ 0]; - _dst[ 1] = -_src[ 1]; - _dst[ 2] = -_src[ 2]; - _dst[ 3] = -_src[ 3]; - _dst[ 4] = _src[ 4]; - _dst[ 5] = _src[ 5]; - _dst[ 6] = _src[ 6]; - _dst[ 7] = _src[ 7]; - _dst[ 8] = -_src[ 8]; - _dst[ 9] = -_src[ 9]; - _dst[10] = -_src[10]; - _dst[11] = -_src[11]; - _dst[12] = _src[12]; - _dst[13] = _src[13]; - _dst[14] = _src[14]; - _dst[15] = _src[15]; - } + const Vec3 ba = sub(_vb, _va); + const Vec3 ca = sub(_vc, _va); + const Vec3 baxca = cross(ba, ca); - /// Convert LH to RH view matrix and vice versa. - inline void mtxViewFlipHandedness(float* _dst, const float* _src) - { - _dst[ 0] = -_src[ 0]; - _dst[ 1] = _src[ 1]; - _dst[ 2] = -_src[ 2]; - _dst[ 3] = _src[ 3]; - _dst[ 4] = -_src[ 4]; - _dst[ 5] = _src[ 5]; - _dst[ 6] = -_src[ 6]; - _dst[ 7] = _src[ 7]; - _dst[ 8] = -_src[ 8]; - _dst[ 9] = _src[ 9]; - _dst[10] = -_src[10]; - _dst[11] = _src[11]; - _dst[12] = -_src[12]; - _dst[13] = _src[13]; - _dst[14] = -_src[14]; - _dst[15] = _src[15]; + return normalize(baxca); } - inline void calcNormal(float _result[3], const float _va[3], const float _vb[3], const float _vc[3]) + inline void calcPlane(Plane& _outPlane, const Vec3& _va, const Vec3& _vb, const Vec3& _vc) { - float ba[3]; - vec3Sub(ba, _vb, _va); - - float ca[3]; - vec3Sub(ca, _vc, _va); - - float baxca[3]; - vec3Cross(baxca, ba, ca); - - vec3Norm(_result, baxca); + Vec3 normal = calcNormal(_va, _vb, _vc); + calcPlane(_outPlane, normal, _va); } - inline void calcPlane(float _result[4], const float _va[3], const float _vb[3], const float _vc[3]) + inline void calcPlane(Plane& _outPlane, const Vec3& _normal, const Vec3& _pos) { - float normal[3]; - calcNormal(normal, _va, _vb, _vc); - calcPlane(_result, normal, _va); + _outPlane.normal = _normal; + _outPlane.dist = -dot(_normal, _pos); } - inline void calcPlane(float _result[4], const float _normal[3], const float _pos[3]) + inline float distance(const Plane& _plane, const Vec3& _pos) { - _result[0] = _normal[0]; - _result[1] = _normal[1]; - _result[2] = _normal[2]; - _result[3] = -vec3Dot(_normal, _pos); + return dot(_plane.normal, _pos) + _plane.dist; } inline BX_CONST_FUNC float toLinear(float _a) diff --git a/3rdparty/bx/include/bx/inline/mpscqueue.inl b/3rdparty/bx/include/bx/inline/mpscqueue.inl index a22cf283815..fcff39bff86 100644 --- a/3rdparty/bx/include/bx/inline/mpscqueue.inl +++ b/3rdparty/bx/include/bx/inline/mpscqueue.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/mutex.inl b/3rdparty/bx/include/bx/inline/mutex.inl index 971ebcaa6a8..7b1ee37c909 100644 --- a/3rdparty/bx/include/bx/inline/mutex.inl +++ b/3rdparty/bx/include/bx/inline/mutex.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/pixelformat.inl b/3rdparty/bx/include/bx/inline/pixelformat.inl index 8ac02813521..72e2c943c86 100644 --- a/3rdparty/bx/include/bx/inline/pixelformat.inl +++ b/3rdparty/bx/include/bx/inline/pixelformat.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -31,6 +31,23 @@ namespace bx return max(-1.0f, float(_value) / _scale); } + // A8 + inline void packA8(void* _dst, const float* _src) + { + uint8_t* dst = (uint8_t*)_dst; + dst[0] = uint8_t(toUnorm(_src[3], 255.0f) ); + } + + inline void unpackA8(float* _dst, const void* _src) + { + const uint8_t* src = (const uint8_t*)_src; + const float aa = fromUnorm(src[0], 255.0f); + _dst[0] = aa; + _dst[1] = aa; + _dst[2] = aa; + _dst[3] = aa; + } + // R8 inline void packR8(void* _dst, const float* _src) { diff --git a/3rdparty/bx/include/bx/inline/readerwriter.inl b/3rdparty/bx/include/bx/inline/readerwriter.inl index 9a365dcee60..66c8d6d45a7 100644 --- a/3rdparty/bx/include/bx/inline/readerwriter.inl +++ b/3rdparty/bx/include/bx/inline/readerwriter.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -273,7 +273,7 @@ namespace bx } template<typename Ty> - int32_t read(ReaderI* _reader, Ty& _value, Error* _err) + inline int32_t read(ReaderI* _reader, Ty& _value, Error* _err) { BX_ERROR_SCOPE(_err); BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() ); @@ -281,7 +281,7 @@ namespace bx } template<typename Ty> - int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian, Error* _err) + inline int32_t readHE(ReaderI* _reader, Ty& _value, bool _fromLittleEndian, Error* _err) { BX_ERROR_SCOPE(_err); BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() ); @@ -329,7 +329,7 @@ namespace bx } template<typename Ty> - int32_t write(WriterI* _writer, const Ty& _value, Error* _err) + inline int32_t write(WriterI* _writer, const Ty& _value, Error* _err) { BX_ERROR_SCOPE(_err); BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() ); @@ -337,7 +337,7 @@ namespace bx } template<typename Ty> - int32_t writeLE(WriterI* _writer, const Ty& _value, Error* _err) + inline int32_t writeLE(WriterI* _writer, const Ty& _value, Error* _err) { BX_ERROR_SCOPE(_err); BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() ); @@ -346,8 +346,14 @@ namespace bx return result; } + template<> + inline int32_t writeLE(WriterI* _writer, const float& _value, Error* _err) + { + return writeLE(_writer, floatToBits(_value), _err); + } + template<typename Ty> - int32_t writeBE(WriterI* _writer, const Ty& _value, Error* _err) + inline int32_t writeBE(WriterI* _writer, const Ty& _value, Error* _err) { BX_ERROR_SCOPE(_err); BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() ); @@ -356,6 +362,12 @@ namespace bx return result; } + template<> + inline int32_t writeBE(WriterI* _writer, const float& _value, Error* _err) + { + return writeBE(_writer, floatToBits(_value), _err); + } + inline int64_t skip(SeekerI* _seeker, int64_t _offset) { return _seeker->seek(_offset, Whence::Current); @@ -392,7 +404,7 @@ namespace bx } template<typename Ty> - int32_t peek(ReaderSeekerI* _reader, Ty& _value, Error* _err) + inline int32_t peek(ReaderSeekerI* _reader, Ty& _value, Error* _err) { BX_ERROR_SCOPE(_err); BX_STATIC_ASSERT(isTriviallyCopyable<Ty>() ); diff --git a/3rdparty/bx/include/bx/inline/ringbuffer.inl b/3rdparty/bx/include/bx/inline/ringbuffer.inl index 51f365546db..d0f0a8b2eda 100644 --- a/3rdparty/bx/include/bx/inline/ringbuffer.inl +++ b/3rdparty/bx/include/bx/inline/ringbuffer.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/rng.inl b/3rdparty/bx/include/bx/inline/rng.inl index 9577bb09aa9..4ac29703f0c 100644 --- a/3rdparty/bx/include/bx/inline/rng.inl +++ b/3rdparty/bx/include/bx/inline/rng.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -103,6 +103,10 @@ namespace bx inline void generateSphereHammersley(void* _data, uint32_t _stride, uint32_t _num, float _scale) { + // Reference(s): + // - Sampling with Hammersley and Halton Points + // https://web.archive.org/web/20190207230709/http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html + uint8_t* data = (uint8_t*)_data; for (uint32_t ii = 0; ii < _num; ii++) diff --git a/3rdparty/bx/include/bx/inline/simd128_langext.inl b/3rdparty/bx/include/bx/inline/simd128_langext.inl index ac08ba7f9de..2c58becd247 100644 --- a/3rdparty/bx/include/bx/inline/simd128_langext.inl +++ b/3rdparty/bx/include/bx/inline/simd128_langext.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/simd128_neon.inl b/3rdparty/bx/include/bx/inline/simd128_neon.inl index 95107eeaa27..1aa40952e31 100644 --- a/3rdparty/bx/include/bx/inline/simd128_neon.inl +++ b/3rdparty/bx/include/bx/inline/simd128_neon.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/simd128_ref.inl b/3rdparty/bx/include/bx/inline/simd128_ref.inl index 6895b24f46a..5cd98c74478 100644 --- a/3rdparty/bx/include/bx/inline/simd128_ref.inl +++ b/3rdparty/bx/include/bx/inline/simd128_ref.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/simd128_sse.inl b/3rdparty/bx/include/bx/inline/simd128_sse.inl index 229c1431fe3..213fe174b98 100644 --- a/3rdparty/bx/include/bx/inline/simd128_sse.inl +++ b/3rdparty/bx/include/bx/inline/simd128_sse.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/simd256_avx.inl b/3rdparty/bx/include/bx/inline/simd256_avx.inl index 4dd9c666f71..221c1d283fc 100644 --- a/3rdparty/bx/include/bx/inline/simd256_avx.inl +++ b/3rdparty/bx/include/bx/inline/simd256_avx.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/simd256_ref.inl b/3rdparty/bx/include/bx/inline/simd256_ref.inl index 0c84d9d82a0..cbcdd726e6a 100644 --- a/3rdparty/bx/include/bx/inline/simd256_ref.inl +++ b/3rdparty/bx/include/bx/inline/simd256_ref.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/simd_ni.inl b/3rdparty/bx/include/bx/inline/simd_ni.inl index eb388513e88..6b78be8a308 100644 --- a/3rdparty/bx/include/bx/inline/simd_ni.inl +++ b/3rdparty/bx/include/bx/inline/simd_ni.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/sort.inl b/3rdparty/bx/include/bx/inline/sort.inl index 27a085362da..85e7b0a9fd0 100644 --- a/3rdparty/bx/include/bx/inline/sort.inl +++ b/3rdparty/bx/include/bx/inline/sort.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/inline/spscqueue.inl b/3rdparty/bx/include/bx/inline/spscqueue.inl index e0fae02ef29..94c05d81712 100644 --- a/3rdparty/bx/include/bx/inline/spscqueue.inl +++ b/3rdparty/bx/include/bx/inline/spscqueue.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -9,7 +9,10 @@ namespace bx { - // http://drdobbs.com/article/print?articleId=210604448&siteSectionName= + // Reference(s): + // - Writing Lock-Free Code: A Corrected Queue + // https://web.archive.org/web/20190207230604/http://www.drdobbs.com/parallel/writing-lock-free-code-a-corrected-queue/210604448 + // inline SpScUnboundedQueue::SpScUnboundedQueue(AllocatorI* _allocator) : m_allocator(_allocator) , m_first(BX_NEW(m_allocator, Node)(NULL) ) diff --git a/3rdparty/bx/include/bx/inline/string.inl b/3rdparty/bx/include/bx/inline/string.inl index a387128679e..61c49339cd8 100644 --- a/3rdparty/bx/include/bx/inline/string.inl +++ b/3rdparty/bx/include/bx/inline/string.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -241,4 +241,43 @@ namespace bx return StringView(_str, _start, _len); } + inline LineReader::LineReader(const bx::StringView& _str) + : m_str(_str) + { + reset(); + } + + inline void LineReader::reset() + { + m_curr = m_str; + m_line = 0; + } + + inline StringView LineReader::next() + { + if (m_curr.getPtr() != m_str.getTerm() ) + { + ++m_line; + + StringView curr(m_curr); + m_curr = bx::strFindNl(m_curr); + + StringView line(curr.getPtr(), m_curr.getPtr() ); + + return strRTrim(line, "\n\r"); + } + + return m_curr; + } + + inline bool LineReader::isDone() const + { + return m_curr.getPtr() == m_str.getTerm(); + } + + inline uint32_t LineReader::getLine() const + { + return m_line; + } + } // namespace bx diff --git a/3rdparty/bx/include/bx/inline/uint32_t.inl b/3rdparty/bx/include/bx/inline/uint32_t.inl index 2a17582b0db..8fc1af6199b 100644 --- a/3rdparty/bx/include/bx/inline/uint32_t.inl +++ b/3rdparty/bx/include/bx/inline/uint32_t.inl @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -307,8 +307,12 @@ namespace bx return result; } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(uint32_t _val) { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return __builtin_popcount(_val); +#else const uint32_t tmp0 = uint32_srl(_val, 1); const uint32_t tmp1 = uint32_and(tmp0, 0x55555555); const uint32_t tmp2 = uint32_sub(_val, tmp1); @@ -328,10 +332,37 @@ namespace bx const uint32_t result = uint32_and(tmpF, 0x3f); return result; +#endif // BX_COMPILER_* } + template<> + inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(uint64_t _val) + { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return __builtin_popcountll(_val); +#else + const uint32_t lo = uint32_t(_val&UINT32_MAX); + const uint32_t hi = uint32_t(_val>>32); + + const uint32_t total = uint32_cntbits(lo) + + uint32_cntbits(hi); + return total; +#endif // BX_COMPILER_* + } + + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(uint8_t _val) { return uint32_cntbits<uint32_t>(_val); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(int8_t _val) { return uint32_cntbits<uint8_t >(_val); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(uint16_t _val) { return uint32_cntbits<uint32_t>(_val); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(int16_t _val) { return uint32_cntbits<uint16_t>(_val); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(int32_t _val) { return uint32_cntbits<uint32_t>(_val); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(int64_t _val) { return uint32_cntbits<uint64_t>(_val); } + + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(uint32_t _val) { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return 0 == _val ? 32 : __builtin_clz(_val); +#else const uint32_t tmp0 = uint32_srl(_val, 1); const uint32_t tmp1 = uint32_or(tmp0, _val); const uint32_t tmp2 = uint32_srl(tmp1, 2); @@ -346,18 +377,64 @@ namespace bx const uint32_t result = uint32_cntbits(tmpA); return result; +#endif // BX_COMPILER_* } + template<> + inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(uint64_t _val) + { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return 0 == _val ? 64 : __builtin_clzll(_val); +#else + return _val & UINT64_C(0xffffffff00000000) + ? uint32_cntlz(uint32_t(_val>>32) ) + : uint32_cntlz(uint32_t(_val) ) + 32 + ; +#endif // BX_COMPILER_* + } + + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(uint8_t _val) { return uint32_cntlz<uint32_t>(_val)-24; } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(int8_t _val) { return uint32_cntlz<uint8_t >(_val); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(uint16_t _val) { return uint32_cntlz<uint32_t>(_val)-16; } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(int16_t _val) { return uint32_cntlz<uint16_t>(_val); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(int32_t _val) { return uint32_cntlz<uint32_t>(_val); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(int64_t _val) { return uint32_cntlz<uint64_t>(_val); } + + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(uint32_t _val) { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return 0 == _val ? 32 : __builtin_ctz(_val); +#else const uint32_t tmp0 = uint32_not(_val); const uint32_t tmp1 = uint32_dec(_val); const uint32_t tmp2 = uint32_and(tmp0, tmp1); const uint32_t result = uint32_cntbits(tmp2); return result; +#endif // BX_COMPILER_* + } + + template<> + inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(uint64_t _val) + { +#if BX_COMPILER_GCC || BX_COMPILER_CLANG + return 0 == _val ? 64 : __builtin_ctzll(_val); +#else + return _val & UINT64_C(0xffffffff) + ? uint32_cnttz(uint32_t(_val) ) + : uint32_cnttz(uint32_t(_val>>32) ) + 32 + ; +#endif // BX_COMPILER_* } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(uint8_t _val) { return bx::min(8u, uint32_cnttz<uint32_t>(_val) ); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(int8_t _val) { return uint32_cnttz<uint8_t >(_val); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(uint16_t _val) { return bx::min(16u, uint32_cnttz<uint32_t>(_val) ); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(int16_t _val) { return uint32_cnttz<uint16_t>(_val); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(int32_t _val) { return uint32_cnttz<uint32_t>(_val); } + template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(int64_t _val) { return uint32_cnttz<uint64_t>(_val); } + inline BX_CONSTEXPR_FUNC uint32_t uint32_part1by1(uint32_t _a) { // shuffle: @@ -468,6 +545,66 @@ namespace bx ; } + inline BX_CONSTEXPR_FUNC uint64_t uint64_li(uint64_t _a) + { + return _a; + } + + inline BX_CONSTEXPR_FUNC uint64_t uint64_dec(uint64_t _a) + { + return _a - 1; + } + + inline BX_CONSTEXPR_FUNC uint64_t uint64_inc(uint64_t _a) + { + return _a + 1; + } + + inline BX_CONSTEXPR_FUNC uint64_t uint64_not(uint64_t _a) + { + return ~_a; + } + + inline BX_CONSTEXPR_FUNC uint64_t uint64_neg(uint64_t _a) + { + return -(int32_t)_a; + } + + inline BX_CONSTEXPR_FUNC uint64_t uint64_ext(uint64_t _a) + { + return ( (int32_t)_a)>>31; + } + + inline BX_CONSTEXPR_FUNC uint64_t uint64_and(uint64_t _a, uint64_t _b) + { + return _a & _b; + } + + inline BX_CONSTEXPR_FUNC uint64_t uint64_andc(uint64_t _a, uint64_t _b) + { + return _a & ~_b; + } + + inline BX_CONSTEXPR_FUNC uint64_t uint64_xor(uint64_t _a, uint64_t _b) + { + return _a ^ _b; + } + + inline BX_CONSTEXPR_FUNC uint64_t uint64_xorl(uint64_t _a, uint64_t _b) + { + return !_a != !_b; + } + + inline BX_CONSTEXPR_FUNC uint64_t uint64_or(uint64_t _a, uint64_t _b) + { + return _a | _b; + } + + inline BX_CONSTEXPR_FUNC uint64_t uint64_orc(uint64_t _a, uint64_t _b) + { + return _a | ~_b; + } + inline BX_CONSTEXPR_FUNC uint64_t uint64_sll(uint64_t _a, int32_t _sa) { return _a << _sa; @@ -537,21 +674,10 @@ namespace bx return result; } - inline BX_CONSTEXPR_FUNC uint32_t strideAlign16(uint32_t _offset, uint32_t _stride) - { - const uint32_t align = uint32_lcm(16, _stride); - const uint32_t mod = uint32_mod(_offset, align); - const uint32_t mask = uint32_cmpeq(mod, 0); - const uint32_t tmp0 = uint32_selb(mask, 0, align); - const uint32_t tmp1 = uint32_add(_offset, tmp0); - const uint32_t result = uint32_sub(tmp1, mod); - - return result; - } - - inline BX_CONSTEXPR_FUNC uint32_t strideAlign256(uint32_t _offset, uint32_t _stride) + template<uint32_t Min> + inline BX_CONSTEXPR_FUNC uint32_t strideAlign(uint32_t _offset, uint32_t _stride) { - const uint32_t align = uint32_lcm(256, _stride); + const uint32_t align = uint32_lcm(Min, _stride); const uint32_t mod = uint32_mod(_offset, align); const uint32_t mask = uint32_cmpeq(mod, 0); const uint32_t tmp0 = uint32_selb(mask, 0, align); diff --git a/3rdparty/bx/include/bx/macros.h b/3rdparty/bx/include/bx/macros.h index 9c72182486b..2f92c1ff424 100644 --- a/3rdparty/bx/include/bx/macros.h +++ b/3rdparty/bx/include/bx/macros.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -115,7 +115,11 @@ /// The return value of the function is solely a function of the arguments. /// -#define BX_CONSTEXPR_FUNC constexpr BX_CONST_FUNC +#if __cplusplus < 201402 +# define BX_CONSTEXPR_FUNC BX_CONST_FUNC +#else +# define BX_CONSTEXPR_FUNC constexpr BX_CONST_FUNC +#endif // __cplusplus < 201402 /// #define BX_STATIC_ASSERT(_condition, ...) static_assert(_condition, "" __VA_ARGS__) diff --git a/3rdparty/bx/include/bx/maputil.h b/3rdparty/bx/include/bx/maputil.h index 78ce6b6f84c..fcdc4b58d97 100644 --- a/3rdparty/bx/include/bx/maputil.h +++ b/3rdparty/bx/include/bx/maputil.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/math.h b/3rdparty/bx/include/bx/math.h index c751efad50b..6e28839a35f 100644 --- a/3rdparty/bx/include/bx/math.h +++ b/3rdparty/bx/include/bx/math.h @@ -1,10 +1,8 @@ /* - * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * Copyright 2011-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ -// FPU math lib - #ifndef BX_MATH_H_HEADER_GUARD #define BX_MATH_H_HEADER_GUARD @@ -55,9 +53,31 @@ namespace bx /// struct Vec3 { + /// + Vec3(); + + /// + explicit constexpr Vec3(float _v); + + /// + constexpr Vec3(float _x, float _y, float _z); + float x, y, z; }; + /// + struct Plane + { + Vec3 normal; + float dist; + }; + + /// + struct Quaternion + { + float x, y, z, w; + }; + /// Returns converted the argument _deg to radians. /// BX_CONST_FUNC float toRad(float _deg); @@ -112,15 +132,15 @@ namespace bx /// Returns the largest integer value not greater than _f. /// - BX_CONST_FUNC float floor(float _f); + BX_CONSTEXPR_FUNC float floor(float _f); /// Returns the smallest integer value not less than _f. /// - BX_CONST_FUNC float ceil(float _f); + BX_CONSTEXPR_FUNC float ceil(float _f); /// Returns the nearest integer value to _f, rounding halfway cases away from zero, /// - BX_CONST_FUNC float round(float _f); + BX_CONSTEXPR_FUNC float round(float _f); /// Returns linear interpolation between two values _a and _b. /// @@ -264,158 +284,123 @@ namespace bx BX_CONST_FUNC float angleLerp(float _a, float _b, float _t); /// - Vec3 load(const void* _ptr); - - /// - void store(void* _ptr, const Vec3& _a); + template<typename Ty> + Ty load(const void* _ptr); /// - BX_CONSTEXPR_FUNC Vec3 abs(const Vec3& _a); + template<typename Ty> + void store(void* _ptr, const Ty& _a); /// - BX_CONSTEXPR_FUNC Vec3 neg(const Vec3& _a); + BX_CONSTEXPR_FUNC Vec3 round(const Vec3 _a); /// - BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, const Vec3& _b); + BX_CONSTEXPR_FUNC Vec3 abs(const Vec3 _a); /// - BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, float _b); + BX_CONSTEXPR_FUNC Vec3 neg(const Vec3 _a); /// - BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, const Vec3& _b); + BX_CONSTEXPR_FUNC Vec3 add(const Vec3 _a, const Vec3 _b); /// - BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, float _b); + BX_CONSTEXPR_FUNC Vec3 add(const Vec3 _a, float _b); /// - BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, const Vec3& _b); + BX_CONSTEXPR_FUNC Vec3 sub(const Vec3 _a, const Vec3 _b); /// - BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, float _b); + BX_CONSTEXPR_FUNC Vec3 sub(const Vec3 _a, float _b); /// - BX_CONSTEXPR_FUNC Vec3 mad(const Vec3& _a, const Vec3& _b, const Vec3& _c); + BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _a, const Vec3 _b); /// - BX_CONSTEXPR_FUNC float dot(const Vec3& _a, const Vec3& _b); + BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _a, float _b); /// - BX_CONSTEXPR_FUNC Vec3 cross(const Vec3& _a, const Vec3& _b); + BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const float _b, const Vec3 _c); /// - BX_CONST_FUNC float length(const Vec3& _a); + BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const Vec3 _b, const Vec3 _c); /// - BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, float _t); + BX_CONSTEXPR_FUNC float dot(const Vec3 _a, const Vec3 _b); /// - BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, const Vec3& _t); + BX_CONSTEXPR_FUNC Vec3 cross(const Vec3 _a, const Vec3 _b); /// - BX_CONST_FUNC Vec3 normalize(const Vec3& _a); + BX_CONST_FUNC float length(const Vec3 _a); /// - BX_CONSTEXPR_FUNC Vec3 min(const Vec3& _a, const Vec3& _b); + BX_CONST_FUNC float distanceSq(const Vec3 _a, const Vec3 _b); /// - BX_CONSTEXPR_FUNC Vec3 max(const Vec3& _a, const Vec3& _b); + BX_CONST_FUNC float distance(const Vec3 _a, const Vec3 _b); /// - BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3& _a); + BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3 _a, const Vec3 _b, float _t); /// - void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n); + BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3 _a, const Vec3 _b, const Vec3 _t); /// - void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n, float _angle); + BX_CONST_FUNC Vec3 normalize(const Vec3 _a); /// - BX_CONST_FUNC Vec3 fromLatLong(float _u, float _v); - - /// - void toLatLong(float* _outU, float* _outV, const Vec3& _dir); - - /// - void vec3Add(float* _result, const float* _a, const float* _b); - - /// - void vec3Sub(float* _result, const float* _a, const float* _b); + BX_CONSTEXPR_FUNC Vec3 min(const Vec3 _a, const Vec3 _b); /// - void vec3Mul(float* _result, const float* _a, const float* _b); + BX_CONSTEXPR_FUNC Vec3 max(const Vec3 _a, const Vec3 _b); /// - void vec3Mul(float* _result, const float* _a, float _b); + BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3 _a); /// - float vec3Dot(const float* _a, const float* _b); + void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3 _n); /// - void vec3Cross(float* _result, const float* _a, const float* _b); + void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3 _n, float _angle); /// - float vec3Length(const float* _a); - - /// - float vec3Norm(float* _result, const float* _a); - - /// Calculate tangent frame from normal. - /// - void vec3TangentFrame(const float* _n, float* _t, float* _b); - - /// Calculate tangent frame from normal and angle. - /// - void vec3TangentFrame(const float* _n, float* _t, float* _b, float _angle); - - /// - void vec3FromLatLong(float* _vec, float _u, float _v); - - /// Convert direction to 2D latitude and longitude. - /// - /// @param[out] _outU U-coordinate. - /// @param[out] _outV V-coordinate. - /// @param[in] _dir Normalized direction vector. - /// - void vec3ToLatLong(float* _outU, float* _outV, const float* _dir); - - /// - void quatIdentity(float* _result); + BX_CONST_FUNC Vec3 fromLatLong(float _u, float _v); /// - void quatMove(float* _result, const float* _a); + void toLatLong(float* _outU, float* _outV, const Vec3 _dir); /// - void quatMulXYZ(float* _result, const float* _qa, const float* _qb); + BX_CONSTEXPR_FUNC Quaternion invert(const Quaternion _a); /// - void quatMul(float* _result, const float* _qa, const float* _qb); + BX_CONSTEXPR_FUNC Vec3 mulXyz(const Quaternion _a, const Quaternion _b); /// - void quatInvert(float* _result, const float* _quat); + BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, const Quaternion _b); /// - float quatDot(const float* _a, const float* _b); + BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _v, const Quaternion _q); /// - void quatNorm(float* _result, const float* _quat); + BX_CONSTEXPR_FUNC float dot(const Quaternion _a, const Quaternion _b); /// - void quatToEuler(float* _result, const float* _quat); + BX_CONSTEXPR_FUNC Quaternion normalize(const Quaternion _a); /// - void quatRotateAxis(float* _result, const float* _axis, float _angle); + BX_CONST_FUNC Vec3 toEuler(const Quaternion _a); /// - void quatRotateX(float* _result, float _ax); + BX_CONST_FUNC Quaternion rotateAxis(const Vec3 _axis, float _angle); /// - void quatRotateY(float* _result, float _ay); + BX_CONST_FUNC Quaternion rotateX(float _ax); /// - void quatRotateZ(float* _result, float _az); + BX_CONST_FUNC Quaternion rotateY(float _ay); /// - void vec3MulQuat(float* _result, const float* _vec, const float* _quat); + BX_CONST_FUNC Quaternion rotateZ(float _az); /// void mtxIdentity(float* _result); @@ -430,109 +415,121 @@ namespace bx void mtxScale(float* _result, float _scale); /// - void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos); - - /// - void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos, float _angle); - - /// - void mtxQuat(float* _result, const float* _quat); - - /// - void mtxQuatTranslation(float* _result, const float* _quat, const float* _translation); - - /// - void mtxQuatTranslationHMD(float* _result, const float* _quat, const float* _translation); - - /// - void mtxLookAtLh(float* _result, const Vec3& _eye, const Vec3& _at, const Vec3& _up = { 0.0f, 1.0f, 0.0f }); - - /// - void mtxLookAtRh(float* _result, const Vec3& _eye, const Vec3& _at, const Vec3& _up = { 0.0f, 1.0f, 0.0f }); - - /// - void mtxLookAt(float* _result, const Vec3& _eye, const Vec3& _at, const Vec3& _up = { 0.0f, 1.0f, 0.0f }); - - /// - void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc); - - /// - void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc); - - /// - void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc); - - /// - void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc); - - /// - void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc); - - /// - void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc); - - /// - void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc); - - /// - void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc); - - /// - void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc); - - /// - void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc); - - /// - void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc); - - /// - void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc); - - /// - void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc); - - /// - void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc); - - /// - void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc); - - /// - void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc); - - /// - void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc); - - /// - void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc); - - /// - void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc); - - /// - void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc); - - /// - void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc); - - /// - void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc); - - /// - void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc); - - /// - void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc); - - /// - void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc); - - /// - void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc); - - /// - void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc); + void mtxFromNormal( + float* _result + , const Vec3& _normal + , float _scale + , const Vec3& _pos + ); + + /// + void mtxFromNormal( + float* _result + , const Vec3& _normal + , float _scale + , const Vec3& _pos + , float _angle + ); + + /// + void mtxQuat(float* _result, const Quaternion& _quat); + + /// + void mtxQuatTranslation(float* _result, const Quaternion& _quat, const Vec3& _translation); + + /// + void mtxQuatTranslationHMD(float* _result, const Quaternion& _quat, const Vec3& _translation); + + /// + void mtxLookAt( + float* _result + , const Vec3& _eye + , const Vec3& _at + , const Vec3& _up = { 0.0f, 1.0f, 0.0f } + , Handness::Enum _handness = Handness::Left + ); + + /// + void mtxProj( + float* _result + , float _ut + , float _dt + , float _lt + , float _rt + , float _near + , float _far + , bool _homogeneousNdc + , Handness::Enum _handness = Handness::Left + ); + + /// + void mtxProj( + float* _result + , const float _fov[4] + , float _near + , float _far + , bool _homogeneousNdc + , Handness::Enum _handness = Handness::Left + ); + + /// + void mtxProj( + float* _result + , float _fovy + , float _aspect + , float _near + , float _far + , bool _homogeneousNdc + , Handness::Enum _handness = Handness::Left + ); + + /// + void mtxProjInf( + float* _result + , const float _fov[4] + , float _near + , bool _homogeneousNdc + , Handness::Enum _handness = Handness::Left + , NearFar::Enum _nearFar = NearFar::Default + ); + + /// + void mtxProjInf( + float* _result + , float _ut + , float _dt + , float _lt + , float _rt + , float _near + , bool _homogeneousNdc + , Handness::Enum _handness = Handness::Left + , NearFar::Enum _nearFar = NearFar::Default + ); + + /// + void mtxProjInf( + float* _result + , float _fovy + , float _aspect + , float _near + , bool _homogeneousNdc + , Handness::Enum _handness = Handness::Left + , NearFar::Enum _nearFar = NearFar::Default + ); + + /// + void mtxOrtho( + float* _result + , float _left + , float _right + , float _bottom + , float _top + , float _near + , float _far + , float _offset + , bool _homogeneousNdc + , Handness::Enum _handness = Handness::Left + ); /// void mtxRotateX(float* _result, float _ax); @@ -553,22 +550,27 @@ namespace bx void mtxRotateZYX(float* _result, float _ax, float _ay, float _az); /// - void mtxSRT(float* _result, float _sx, float _sy, float _sz, float _ax, float _ay, float _az, float _tx, float _ty, float _tz); + void mtxSRT( + float* _result + , float _sx + , float _sy + , float _sz + , float _ax + , float _ay + , float _az + , float _tx + , float _ty + , float _tz + ); /// - void vec3MulMtx(float* _result, const float* _vec, const float* _mat); + Vec3 mul(const Vec3& _vec, const float* _mat); /// - void vec3MulMtxXyz0(float* _result, const float* _vec, const float* _mat); + Vec3 mulXyz0(const Vec3& _vec, const float* _mat); /// - void vec3MulMtxH(float* _result, const float* _vec, const float* _mat); - - /// - void vec4Mul(float* _result, const float* _a, const float* _b); - - /// - void vec4Mul(float* _result, const float* _a, float _b); + Vec3 mulH(const Vec3& _vec, const float* _mat); /// void vec4MulMtx(float* _result, const float* _vec, const float* _mat); @@ -585,22 +587,23 @@ namespace bx /// void mtxInverse(float* _result, const float* _a); - /// Convert LH to RH projection matrix and vice versa. /// - void mtxProjFlipHandedness(float* _dst, const float* _src); + void mtx3Cofactor(float* _result, const float* _a); + + /// + void mtxCofactor(float* _result, const float* _a); - /// Convert LH to RH view matrix and vice versa. /// - void mtxViewFlipHandedness(float* _dst, const float* _src); + Vec3 calcNormal(const Vec3& _va, const Vec3& _vb, const Vec3& _vc); /// - void calcNormal(float _result[3], const float _va[3], const float _vb[3], const float _vc[3]); + void calcPlane(Plane& _outPlane, const Vec3& _va, const Vec3& _vb, const Vec3& _vc); /// - void calcPlane(float _result[4], const float _va[3], const float _vb[3], const float _vc[3]); + void calcPlane(Plane& _outPlane, const Vec3& _normal, const Vec3& _pos); /// - void calcPlane(float _result[4], const float _normal[3], const float _pos[3]); + float distance(const Plane& _plane, const Vec3& _pos); /// void calcLinearFit2D(float _result[2], const void* _points, uint32_t _stride, uint32_t _numPoints); diff --git a/3rdparty/bx/include/bx/mpscqueue.h b/3rdparty/bx/include/bx/mpscqueue.h index 003dfe8f4f8..bbc80049872 100644 --- a/3rdparty/bx/include/bx/mpscqueue.h +++ b/3rdparty/bx/include/bx/mpscqueue.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/mutex.h b/3rdparty/bx/include/bx/mutex.h index 213fc68c70e..8f8ec18de08 100644 --- a/3rdparty/bx/include/bx/mutex.h +++ b/3rdparty/bx/include/bx/mutex.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/os.h b/3rdparty/bx/include/bx/os.h index 92edacd21d1..2a8cb0d6883 100644 --- a/3rdparty/bx/include/bx/os.h +++ b/3rdparty/bx/include/bx/os.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/pixelformat.h b/3rdparty/bx/include/bx/pixelformat.h index c75b39836d5..03c5f62415b 100644 --- a/3rdparty/bx/include/bx/pixelformat.h +++ b/3rdparty/bx/include/bx/pixelformat.h @@ -1,5 +1,5 @@ /* - * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * Copyright 2011-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -41,6 +41,10 @@ namespace bx /// float fromSnorm(int32_t _value, float _scale); + // A8 + void packA8(void* _dst, const float* _src); + void unpackA8(float* _dst, const void* _src); + // R8 void packR8(void* _dst, const float* _src); void unpackR8(float* _dst, const void* _src); diff --git a/3rdparty/bx/include/bx/platform.h b/3rdparty/bx/include/bx/platform.h index e0031ec2c38..8195cfe36c8 100644 --- a/3rdparty/bx/include/bx/platform.h +++ b/3rdparty/bx/include/bx/platform.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -48,6 +48,7 @@ #define BX_PLATFORM_ANDROID 0 #define BX_PLATFORM_BSD 0 #define BX_PLATFORM_EMSCRIPTEN 0 +#define BX_PLATFORM_HAIKU 0 #define BX_PLATFORM_HURD 0 #define BX_PLATFORM_IOS 0 #define BX_PLATFORM_LINUX 0 @@ -133,8 +134,14 @@ #endif // #if BX_CPU_PPC -# undef BX_CPU_ENDIAN_BIG -# define BX_CPU_ENDIAN_BIG 1 +// _LITTLE_ENDIAN exists on ppc64le. +# if _LITTLE_ENDIAN +# undef BX_CPU_ENDIAN_LITTLE +# define BX_CPU_ENDIAN_LITTLE 1 +# else +# undef BX_CPU_ENDIAN_BIG +# define BX_CPU_ENDIAN_BIG 1 +# endif #else # undef BX_CPU_ENDIAN_LITTLE # define BX_CPU_ENDIAN_LITTLE 1 @@ -213,6 +220,9 @@ #elif defined(__NX__) # undef BX_PLATFORM_NX # define BX_PLATFORM_NX 1 +#elif defined(__HAIKU__) +# undef BX_PLATFORM_HAIKU +# define BX_PLATFORM_HAIKU 1 #endif // #if !BX_CRT_NONE @@ -229,7 +239,7 @@ # elif defined(__MINGW32__) || defined(__MINGW64__) # undef BX_CRT_MINGW # define BX_CRT_MINGW 1 -# elif defined(__apple_build_version__) || defined(__ORBIS__) || defined(__EMSCRIPTEN__) || defined(__llvm__) +# elif defined(__apple_build_version__) || defined(__ORBIS__) || defined(__EMSCRIPTEN__) || defined(__llvm__) || defined(__HAIKU__) # undef BX_CRT_LIBCXX # define BX_CRT_LIBCXX 1 # endif // @@ -246,10 +256,12 @@ # endif // BX_CRT_* #endif // !BX_CRT_NONE +/// #define BX_PLATFORM_POSIX (0 \ || BX_PLATFORM_ANDROID \ || BX_PLATFORM_BSD \ || BX_PLATFORM_EMSCRIPTEN \ + || BX_PLATFORM_HAIKU \ || BX_PLATFORM_HURD \ || BX_PLATFORM_IOS \ || BX_PLATFORM_LINUX \ @@ -260,10 +272,12 @@ || BX_PLATFORM_STEAMLINK \ ) +/// #define BX_PLATFORM_NONE !(0 \ || BX_PLATFORM_ANDROID \ || BX_PLATFORM_BSD \ || BX_PLATFORM_EMSCRIPTEN \ + || BX_PLATFORM_HAIKU \ || BX_PLATFORM_HURD \ || BX_PLATFORM_IOS \ || BX_PLATFORM_LINUX \ @@ -277,6 +291,42 @@ || BX_PLATFORM_XBOXONE \ ) +/// +#define BX_PLATFORM_OS_CONSOLE (0 \ + || BX_PLATFORM_NX \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOXONE \ + ) + +/// +#define BX_PLATFORM_OS_DESKTOP (0 \ + || BX_PLATFORM_BSD \ + || BX_PLATFORM_HAIKU \ + || BX_PLATFORM_HURD \ + || BX_PLATFORM_LINUX \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_WINDOWS \ + ) + +/// +#define BX_PLATFORM_OS_EMBEDDED (0 \ + || BX_PLATFORM_RPI \ + || BX_PLATFORM_STEAMLINK \ + ) + +/// +#define BX_PLATFORM_OS_MOBILE (0 \ + || BX_PLATFORM_ANDROID \ + || BX_PLATFORM_IOS \ + ) + +/// +#define BX_PLATFORM_OS_WEB (0 \ + || BX_PLATFORM_EMSCRIPTEN \ + ) + +/// #if BX_COMPILER_GCC # define BX_COMPILER_NAME "GCC " \ BX_STRINGIZE(__GNUC__) "." \ @@ -288,7 +338,9 @@ BX_STRINGIZE(__clang_minor__) "." \ BX_STRINGIZE(__clang_patchlevel__) #elif BX_COMPILER_MSVC -# if BX_COMPILER_MSVC >= 1910 // Visual Studio 2017 +# if BX_COMPILER_MSVC >= 1920 // Visual Studio 2019 +# define BX_COMPILER_NAME "MSVC 16.0" +# elif BX_COMPILER_MSVC >= 1910 // Visual Studio 2017 # define BX_COMPILER_NAME "MSVC 15.0" # elif BX_COMPILER_MSVC >= 1900 // Visual Studio 2015 # define BX_COMPILER_NAME "MSVC 14.0" @@ -315,6 +367,8 @@ BX_STRINGIZE(__EMSCRIPTEN_major__) "." \ BX_STRINGIZE(__EMSCRIPTEN_minor__) "." \ BX_STRINGIZE(__EMSCRIPTEN_tiny__) +#elif BX_PLATFORM_HAIKU +# define BX_PLATFORM_NAME "Haiku" #elif BX_PLATFORM_HURD # define BX_PLATFORM_NAME "Hurd" #elif BX_PLATFORM_IOS @@ -383,4 +437,23 @@ # define BX_ARCH_NAME "64-bit" #endif // BX_ARCH_ +#if BX_COMPILER_MSVC +# define BX_CPP_NAME "C++MsvcUnknown" +#elif defined(__cplusplus) +# if __cplusplus < 201103L +# error "Pre-C++11 compiler is not supported!" +# elif __cplusplus < 201402L +# define BX_CPP_NAME "C++11" +# elif __cplusplus < 201703L +# define BX_CPP_NAME "C++14" +# elif __cplusplus < 201704L +# define BX_CPP_NAME "C++17" +# else +// See: https://gist.github.com/bkaradzic/2e39896bc7d8c34e042b#orthodox-c +# define BX_CPP_NAME "C++WayTooModern" +# endif // BX_CPP_NAME +#else +# define BX_CPP_NAME "C++Unknown" +#endif // defined(__cplusplus) + #endif // BX_PLATFORM_H_HEADER_GUARD diff --git a/3rdparty/bx/include/bx/process.h b/3rdparty/bx/include/bx/process.h index 8369829527b..222b8ed79a8 100644 --- a/3rdparty/bx/include/bx/process.h +++ b/3rdparty/bx/include/bx/process.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/readerwriter.h b/3rdparty/bx/include/bx/readerwriter.h index 0d8e13545a8..ed61f46aa82 100644 --- a/3rdparty/bx/include/bx/readerwriter.h +++ b/3rdparty/bx/include/bx/readerwriter.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -10,6 +10,7 @@ #include "endian.h" #include "error.h" #include "filepath.h" +#include "math.h" #include "string.h" #include "uint32_t.h" @@ -21,94 +22,116 @@ BX_ERROR_RESULT(BX_ERROR_READERWRITER_ALREADY_OPEN, BX_MAKEFOURCC('R', 'W', 0, 5 namespace bx { - /// + /// The position from where offset is added. struct Whence { + /// Whence values: enum Enum { - Begin, - Current, - End, + Begin, //!< From begining of file. + Current, //!< From current position of file. + End, //!< From end of file. }; }; - /// + /// Reader interface. struct BX_NO_VTABLE ReaderI { + /// virtual ~ReaderI() = 0; + + /// virtual int32_t read(void* _data, int32_t _size, Error* _err) = 0; }; - /// + /// Writer interface. struct BX_NO_VTABLE WriterI { + /// virtual ~WriterI() = 0; + + /// virtual int32_t write(const void* _data, int32_t _size, Error* _err) = 0; }; - /// + /// Seeker interface. struct BX_NO_VTABLE SeekerI { + /// virtual ~SeekerI() = 0; + + /// virtual int64_t seek(int64_t _offset = 0, Whence::Enum _whence = Whence::Current) = 0; }; - /// + /// Reader seeker interface. struct BX_NO_VTABLE ReaderSeekerI : public ReaderI, public SeekerI { }; - /// + /// Writer seeker interface. struct BX_NO_VTABLE WriterSeekerI : public WriterI, public SeekerI { }; - /// + /// Open for reading interface. struct BX_NO_VTABLE ReaderOpenI { + /// virtual ~ReaderOpenI() = 0; + + /// virtual bool open(const FilePath& _filePath, Error* _err) = 0; }; - /// + /// Open for writing interface. struct BX_NO_VTABLE WriterOpenI { + /// virtual ~WriterOpenI() = 0; + + /// virtual bool open(const FilePath& _filePath, bool _append, Error* _err) = 0; }; - /// + /// Open process interface. struct BX_NO_VTABLE ProcessOpenI { + /// virtual ~ProcessOpenI() = 0; + + /// virtual bool open(const FilePath& _filePath, const StringView& _args, Error* _err) = 0; }; - /// + /// Closer interface. struct BX_NO_VTABLE CloserI { + /// virtual ~CloserI() = 0; + + /// virtual void close() = 0; }; - /// + /// File reader interface. struct BX_NO_VTABLE FileReaderI : public ReaderOpenI, public CloserI, public ReaderSeekerI { }; - /// + /// File writer interface. struct BX_NO_VTABLE FileWriterI : public WriterOpenI, public CloserI, public WriterSeekerI { }; - /// + /// Memory block interface. struct BX_NO_VTABLE MemoryBlockI { virtual void* more(uint32_t _size = 0) = 0; virtual uint32_t getSize() = 0; }; - /// + /// Static memory block interface. class StaticMemoryBlock : public MemoryBlockI { public: @@ -125,11 +148,11 @@ namespace bx virtual uint32_t getSize() override; private: - void* m_data; + void* m_data; uint32_t m_size; }; - /// + /// Memory block. class MemoryBlock : public MemoryBlockI { public: @@ -147,8 +170,8 @@ namespace bx private: AllocatorI* m_allocator; - void* m_data; - uint32_t m_size; + void* m_data; + uint32_t m_size; }; /// Sizer writer. Dummy writter that only counts number of bytes written into it. @@ -172,7 +195,7 @@ namespace bx int64_t m_top; }; - /// + /// Memory reader. class MemoryReader : public ReaderSeekerI { public: @@ -203,7 +226,7 @@ namespace bx int64_t m_top; }; - /// + /// Memory writer. class MemoryWriter : public WriterSeekerI { public: @@ -222,9 +245,9 @@ namespace bx private: MemoryBlockI* m_memBlock; uint8_t* m_data; - int64_t m_pos; - int64_t m_top; - int64_t m_size; + int64_t m_pos; + int64_t m_top; + int64_t m_size; }; /// Static (fixed size) memory block writer. diff --git a/3rdparty/bx/include/bx/ringbuffer.h b/3rdparty/bx/include/bx/ringbuffer.h index db44da8432e..2a93b985b4a 100644 --- a/3rdparty/bx/include/bx/ringbuffer.h +++ b/3rdparty/bx/include/bx/ringbuffer.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/rng.h b/3rdparty/bx/include/bx/rng.h index 87ba511e513..5469b5efd9c 100644 --- a/3rdparty/bx/include/bx/rng.h +++ b/3rdparty/bx/include/bx/rng.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -67,9 +67,7 @@ namespace bx template <typename Ty> bx::Vec3 randUnitHemisphere(Ty* _rng, const bx::Vec3& _normal); - /// Sampling with Hammersley and Halton Points - /// http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html - /// + /// Sampling with Hammersley and Halton Points. void generateSphereHammersley(void* _data, uint32_t _stride, uint32_t _num, float _scale = 1.0f); /// Fisher-Yates shuffle. diff --git a/3rdparty/bx/include/bx/semaphore.h b/3rdparty/bx/include/bx/semaphore.h index 6d944ed2919..e3bd3899305 100644 --- a/3rdparty/bx/include/bx/semaphore.h +++ b/3rdparty/bx/include/bx/semaphore.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/settings.h b/3rdparty/bx/include/bx/settings.h index 7797cfac2bf..7dd45e626fb 100644 --- a/3rdparty/bx/include/bx/settings.h +++ b/3rdparty/bx/include/bx/settings.h @@ -1,5 +1,5 @@ /* - * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * Copyright 2011-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/simd_t.h b/3rdparty/bx/include/bx/simd_t.h index 33c3f48a954..0c41844655b 100644 --- a/3rdparty/bx/include/bx/simd_t.h +++ b/3rdparty/bx/include/bx/simd_t.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/sort.h b/3rdparty/bx/include/bx/sort.h index 1506fb8307b..b32febd90ff 100644 --- a/3rdparty/bx/include/bx/sort.h +++ b/3rdparty/bx/include/bx/sort.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/spscqueue.h b/3rdparty/bx/include/bx/spscqueue.h index f34b65dfada..7ea7c448750 100644 --- a/3rdparty/bx/include/bx/spscqueue.h +++ b/3rdparty/bx/include/bx/spscqueue.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/string.h b/3rdparty/bx/include/bx/string.h index e0800562d71..43798a4f549 100644 --- a/3rdparty/bx/include/bx/string.h +++ b/3rdparty/bx/include/bx/string.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -21,6 +21,7 @@ namespace bx }; /// Non-zero-terminated string view. + /// class StringView { public: @@ -77,9 +78,16 @@ namespace bx /// void clear(); + /// Returns pointer to non-terminated string. + /// + /// @attention Use of this pointer in standard C/C++ functions is not safe. You must use it + /// in conjunction with `getTerm()` or getLength()`. /// const char* getPtr() const; + /// Returns pointer past last character in string view. + /// + /// @attention Dereferencing this pointer is not safe. /// const char* getTerm() const; @@ -261,7 +269,7 @@ namespace bx StringView findIdentifierMatch(const StringView& _str, const StringView& _word); /// Finds any identifier from NULL terminated array of identifiers. - StringView findIdentifierMatch(const StringView& _str, const char** _words); + StringView findIdentifierMatch(const StringView& _str, const char** _words, int32_t _num = INT32_MAX); /// Cross platform implementation of vsnprintf that returns number of /// characters which would have been written to the final string if @@ -273,6 +281,12 @@ namespace bx /// enough space had been available. int32_t snprintf(char* _out, int32_t _max, const char* _format, ...); + /// + int32_t vprintf(const char* _format, va_list _argList); + + /// + int32_t printf(const char* _format, ...); + /// Templatized snprintf. template <typename Ty> void stringPrintfVargs(Ty& _out, const char* _format, va_list _argList); @@ -321,6 +335,31 @@ namespace bx /// Converts string to 32-bit unsigned integer value. bool fromString(uint32_t* _out, const StringView& _str); + /// + class LineReader + { + public: + /// + LineReader(const bx::StringView& _str); + + /// + void reset(); + + /// + StringView next(); + + /// + bool isDone() const; + + /// + uint32_t getLine() const; + + private: + const bx::StringView m_str; + bx::StringView m_curr; + uint32_t m_line; + }; + } // namespace bx #include "inline/string.inl" diff --git a/3rdparty/bx/include/bx/thread.h b/3rdparty/bx/include/bx/thread.h index 087bd3d4a57..2526741ce08 100644 --- a/3rdparty/bx/include/bx/thread.h +++ b/3rdparty/bx/include/bx/thread.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/timer.h b/3rdparty/bx/include/bx/timer.h index b0b0b403a8b..bbe5e084d4f 100644 --- a/3rdparty/bx/include/bx/timer.h +++ b/3rdparty/bx/include/bx/timer.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/bx/uint32_t.h b/3rdparty/bx/include/bx/uint32_t.h index 3d0afcb7124..3eb8bdfd3c8 100644 --- a/3rdparty/bx/include/bx/uint32_t.h +++ b/3rdparty/bx/include/bx/uint32_t.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ @@ -149,14 +149,18 @@ namespace bx /// Count number of bits set. /// - BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(uint32_t _val); + template<typename Ty> + BX_CONSTEXPR_FUNC uint32_t uint32_cntbits(Ty _val); /// Count number of leading zeros. /// - BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(uint32_t _val); + template<typename Ty> + BX_CONSTEXPR_FUNC uint32_t uint32_cntlz(Ty _val); + /// Count number of trailing zeros. /// - BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(uint32_t _val); + template<typename Ty> + BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(Ty _val); /// BX_CONSTEXPR_FUNC uint32_t uint32_part1by1(uint32_t _a); @@ -170,16 +174,41 @@ namespace bx /// BX_CONSTEXPR_FUNC uint32_t uint32_nextpow2(uint32_t _a); - /// Count number of bits set. /// - BX_CONSTEXPR_FUNC uint32_t uint64_cntbits(uint64_t _val); + BX_CONSTEXPR_FUNC uint64_t uint64_li(uint64_t _a); + + /// + BX_CONSTEXPR_FUNC uint64_t uint64_dec(uint64_t _a); + + /// + BX_CONSTEXPR_FUNC uint64_t uint64_inc(uint64_t _a); + + /// + BX_CONSTEXPR_FUNC uint64_t uint64_not(uint64_t _a); + + /// + BX_CONSTEXPR_FUNC uint64_t uint64_neg(uint64_t _a); + + /// + BX_CONSTEXPR_FUNC uint64_t uint64_ext(uint64_t _a); - /// Count number of leading zeros. /// - BX_CONSTEXPR_FUNC uint32_t uint64_cntlz(uint64_t _val); + BX_CONSTEXPR_FUNC uint64_t uint64_and(uint64_t _a, uint64_t _b); /// - BX_CONSTEXPR_FUNC uint32_t uint64_cnttz(uint64_t _val); + BX_CONSTEXPR_FUNC uint64_t uint64_andc(uint64_t _a, uint64_t _b); + + /// + BX_CONSTEXPR_FUNC uint64_t uint64_xor(uint64_t _a, uint64_t _b); + + /// + BX_CONSTEXPR_FUNC uint64_t uint64_xorl(uint64_t _a, uint64_t _b); + + /// + BX_CONSTEXPR_FUNC uint64_t uint64_or(uint64_t _a, uint64_t _b); + + /// + BX_CONSTEXPR_FUNC uint64_t uint64_orc(uint64_t _a, uint64_t _b); /// BX_CONSTEXPR_FUNC uint64_t uint64_sll(uint64_t _a, int32_t _sa); @@ -217,13 +246,10 @@ namespace bx /// BX_CONSTEXPR_FUNC uint32_t strideAlign(uint32_t _offset, uint32_t _stride); - /// Align to arbitrary stride and 16-bytes. + /// Align to arbitrary stride and Min bytes. /// - BX_CONSTEXPR_FUNC uint32_t strideAlign16(uint32_t _offset, uint32_t _stride); - - /// Align to arbitrary stride and 256-bytes. - /// - BX_CONSTEXPR_FUNC uint32_t strideAlign256(uint32_t _offset, uint32_t _stride); + template<uint32_t Min> + BX_CONSTEXPR_FUNC uint32_t strideAlign(uint32_t _offset, uint32_t _stride); /// Convert float to half-float. /// diff --git a/3rdparty/bx/include/bx/url.h b/3rdparty/bx/include/bx/url.h index 9e00d8348b4..320db14e398 100644 --- a/3rdparty/bx/include/bx/url.h +++ b/3rdparty/bx/include/bx/url.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. + * Copyright 2010-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ diff --git a/3rdparty/bx/include/compat/msvc/dirent.h b/3rdparty/bx/include/compat/msvc/dirent.h index a08d0fa4df3..3177d335f75 100644 --- a/3rdparty/bx/include/compat/msvc/dirent.h +++ b/3rdparty/bx/include/compat/msvc/dirent.h @@ -1,28 +1,10 @@ /* - * dirent.h - dirent API for Microsoft Visual Studio + * Dirent interface for Microsoft Visual Studio * - * Copyright (C) 2006-2012 Toni Ronkko - * - * 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 TONI RONKKO 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. - * - * $Id: dirent.h,v 1.20 2014/03/19 17:52:23 tronkko Exp $ + * Copyright (C) 1998-2019 Toni Ronkko + * This file is part of dirent. Dirent may be freely distributed + * under the MIT license. For all details and documentation, see + * https://github.com/tronkko/dirent */ #ifndef DIRENT_H #define DIRENT_H @@ -36,21 +18,16 @@ #endif // _MSC_VER /* - * Define architecture flags so we don't need to include windows.h. - * Avoiding windows.h makes it simpler to use windows sockets in conjunction - * with dirent.h. + * Include windows.h without Windows Sockets 1.1 to prevent conflicts with + * Windows Sockets 2.0. */ -#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86) -# define _X86_ -#endif -#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64) -#define _AMD64_ +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN #endif +#include <windows.h> #include <stdio.h> #include <stdarg.h> -#include <windef.h> -#include <winbase.h> #include <wchar.h> #include <string.h> #include <stdlib.h> @@ -70,54 +47,109 @@ # define FILE_ATTRIBUTE_DEVICE 0x40 #endif -/* File type and permission flags for stat() */ +/* File type and permission flags for stat(), general mask */ #if !defined(S_IFMT) -# define S_IFMT _S_IFMT /* File type mask */ +# define S_IFMT _S_IFMT #endif + +/* Directory bit */ #if !defined(S_IFDIR) -# define S_IFDIR _S_IFDIR /* Directory */ +# define S_IFDIR _S_IFDIR #endif + +/* Character device bit */ #if !defined(S_IFCHR) -# define S_IFCHR _S_IFCHR /* Character device */ +# define S_IFCHR _S_IFCHR #endif + +/* Pipe bit */ #if !defined(S_IFFIFO) -# define S_IFFIFO _S_IFFIFO /* Pipe */ +# define S_IFFIFO _S_IFFIFO #endif + +/* Regular file bit */ #if !defined(S_IFREG) -# define S_IFREG _S_IFREG /* Regular file */ +# define S_IFREG _S_IFREG #endif + +/* Read permission */ #if !defined(S_IREAD) -# define S_IREAD _S_IREAD /* Read permission */ +# define S_IREAD _S_IREAD #endif + +/* Write permission */ #if !defined(S_IWRITE) -# define S_IWRITE _S_IWRITE /* Write permission */ +# define S_IWRITE _S_IWRITE #endif + +/* Execute permission */ #if !defined(S_IEXEC) -# define S_IEXEC _S_IEXEC /* Execute permission */ +# define S_IEXEC _S_IEXEC #endif + +/* Pipe */ #if !defined(S_IFIFO) -# define S_IFIFO _S_IFIFO /* Pipe */ +# define S_IFIFO _S_IFIFO #endif + +/* Block device */ #if !defined(S_IFBLK) -# define S_IFBLK 0 /* Block device */ +# define S_IFBLK 0 #endif + +/* Link */ #if !defined(S_IFLNK) -# define S_IFLNK 0 /* Link */ +# define S_IFLNK 0 #endif + +/* Socket */ #if !defined(S_IFSOCK) -# define S_IFSOCK 0 /* Socket */ +# define S_IFSOCK 0 +#endif + +/* Read user permission */ +#if !defined(S_IRUSR) +# define S_IRUSR S_IREAD +#endif + +/* Write user permission */ +#if !defined(S_IWUSR) +# define S_IWUSR S_IWRITE +#endif + +/* Execute user permission */ +#if !defined(S_IXUSR) +# define S_IXUSR 0 +#endif + +/* Read group permission */ +#if !defined(S_IRGRP) +# define S_IRGRP 0 +#endif + +/* Write group permission */ +#if !defined(S_IWGRP) +# define S_IWGRP 0 #endif -#if defined(_MSC_VER) -# define S_IRUSR S_IREAD /* Read user */ -# define S_IWUSR S_IWRITE /* Write user */ -# define S_IXUSR 0 /* Execute user */ -# define S_IRGRP 0 /* Read group */ -# define S_IWGRP 0 /* Write group */ -# define S_IXGRP 0 /* Execute group */ -# define S_IROTH 0 /* Read others */ -# define S_IWOTH 0 /* Write others */ -# define S_IXOTH 0 /* Execute others */ +/* Execute group permission */ +#if !defined(S_IXGRP) +# define S_IXGRP 0 +#endif + +/* Read others permission */ +#if !defined(S_IROTH) +# define S_IROTH 0 +#endif + +/* Write others permission */ +#if !defined(S_IWOTH) +# define S_IWOTH 0 +#endif + +/* Execute others permission */ +#if !defined(S_IXOTH) +# define S_IXOTH 0 #endif /* Maximum length of file name */ @@ -132,14 +164,14 @@ #endif /* File type flags for d_type */ -#define DT_UNKNOWN 0 -#define DT_REG S_IFREG -#define DT_DIR S_IFDIR -#define DT_FIFO S_IFIFO -#define DT_SOCK S_IFSOCK -#define DT_CHR S_IFCHR -#define DT_BLK S_IFBLK -#define DT_LNK S_IFLNK +#define DT_UNKNOWN 0 +#define DT_REG S_IFREG +#define DT_DIR S_IFDIR +#define DT_FIFO S_IFIFO +#define DT_SOCK S_IFSOCK +#define DT_CHR S_IFCHR +#define DT_BLK S_IFBLK +#define DT_LNK S_IFLNK /* Macros for converting between st_mode and d_type */ #define IFTODT(mode) ((mode) & S_IFMT) @@ -151,39 +183,33 @@ * only defined for compatibility. These macros should always return false * on Windows. */ -#ifndef S_ISFIFO +#if !defined(S_ISFIFO) # define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) #endif - -#ifndef S_ISDIR -# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#if !defined(S_ISDIR) +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) #endif - -#ifndef S_ISREG -# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#if !defined(S_ISREG) +# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) #endif - -#ifndef S_ISLNK -# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#if !defined(S_ISLNK) +# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) #endif - -#ifndef S_ISSOCK +#if !defined(S_ISSOCK) # define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) #endif - -#ifndef S_ISCHR -# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#if !defined(S_ISCHR) +# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) #endif - -#ifndef S_ISBLK -# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) +#if !defined(S_ISBLK) +# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) #endif -/* Return the exact length of d_namlen without zero terminator */ +/* Return the exact length of the file name without zero terminator */ #define _D_EXACT_NAMLEN(p) ((p)->d_namlen) -/* Return number of bytes needed to store d_namlen */ -#define _D_ALLOC_NAMLEN(p) (PATH_MAX) +/* Return the maximum size of a file name */ +#define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1) #ifdef __cplusplus @@ -193,45 +219,63 @@ extern "C" { /* Wide-character version */ struct _wdirent { - long d_ino; /* Always zero */ - unsigned short d_reclen; /* Structure size */ - size_t d_namlen; /* Length of name without \0 */ - int d_type; /* File type */ - wchar_t d_name[PATH_MAX]; /* File name */ + /* Always zero */ + long d_ino; + + /* File position within stream */ + long d_off; + + /* Structure size */ + unsigned short d_reclen; + + /* Length of name without \0 */ + size_t d_namlen; + + /* File type */ + int d_type; + + /* File name */ + wchar_t d_name[PATH_MAX+1]; }; typedef struct _wdirent _wdirent; struct _WDIR { - struct _wdirent ent; /* Current directory entry */ - WIN32_FIND_DATAW data; /* Private file data */ - int cached; /* True if data is valid */ - HANDLE handle; /* Win32 search handle */ - wchar_t *patt; /* Initial directory name */ + /* Current directory entry */ + struct _wdirent ent; + + /* Private file data */ + WIN32_FIND_DATAW data; + + /* True if data is valid */ + int cached; + + /* Win32 search handle */ + HANDLE handle; + + /* Initial directory name */ + wchar_t *patt; }; typedef struct _WDIR _WDIR; -static _WDIR *_wopendir (const wchar_t *dirname); -static struct _wdirent *_wreaddir (_WDIR *dirp); -static int _wclosedir (_WDIR *dirp); -static void _wrewinddir (_WDIR* dirp); +/* Multi-byte character version */ +struct dirent { + /* Always zero */ + long d_ino; + /* File position within stream */ + long d_off; -/* For compatibility with Symbian */ -#define wdirent _wdirent -#define WDIR _WDIR -#define wopendir _wopendir -#define wreaddir _wreaddir -#define wclosedir _wclosedir -#define wrewinddir _wrewinddir + /* Structure size */ + unsigned short d_reclen; + /* Length of name without \0 */ + size_t d_namlen; -/* Multi-byte character versions */ -struct dirent { - long d_ino; /* Always zero */ - unsigned short d_reclen; /* Structure size */ - size_t d_namlen; /* Length of name without \0 */ - int d_type; /* File type */ - char d_name[PATH_MAX]; /* File name */ + /* File type */ + int d_type; + + /* File name */ + char d_name[PATH_MAX+1]; }; typedef struct dirent dirent; @@ -241,10 +285,41 @@ struct DIR { }; typedef struct DIR DIR; + +/* Dirent functions */ static DIR *opendir (const char *dirname); +static _WDIR *_wopendir (const wchar_t *dirname); + static struct dirent *readdir (DIR *dirp); +static struct _wdirent *_wreaddir (_WDIR *dirp); + +static int readdir_r( + DIR *dirp, struct dirent *entry, struct dirent **result); +static int _wreaddir_r( + _WDIR *dirp, struct _wdirent *entry, struct _wdirent **result); + static int closedir (DIR *dirp); +static int _wclosedir (_WDIR *dirp); + static void rewinddir (DIR* dirp); +static void _wrewinddir (_WDIR* dirp); + +static int scandir (const char *dirname, struct dirent ***namelist, + int (*filter)(const struct dirent*), + int (*compare)(const struct dirent**, const struct dirent**)); + +static int alphasort (const struct dirent **a, const struct dirent **b); + +static int versionsort (const struct dirent **a, const struct dirent **b); + + +/* For compatibility with Symbian */ +#define wdirent _wdirent +#define WDIR _WDIR +#define wopendir _wopendir +#define wreaddir _wreaddir +#define wclosedir _wclosedir +#define wrewinddir _wrewinddir /* Internal utility functions */ @@ -267,6 +342,7 @@ static int dirent_wcstombs_s( static void dirent_set_errno (int error); + /* * Open directory stream DIRNAME for read and return a pointer to the * internal working area that is used to retrieve individual directory @@ -277,7 +353,8 @@ _wopendir( const wchar_t *dirname) { _WDIR *dirp = NULL; - int error; + DWORD n; + wchar_t *p; /* Must have directory name */ if (dirname == NULL || dirname[0] == '\0') { @@ -287,96 +364,120 @@ _wopendir( /* Allocate new _WDIR structure */ dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); - if (dirp != NULL) { - DWORD n; - - /* Reset _WDIR structure */ - dirp->handle = INVALID_HANDLE_VALUE; - dirp->patt = NULL; - dirp->cached = 0; - - /* Compute the length of full path plus zero terminator */ - n = GetFullPathNameW (dirname, 0, NULL, NULL); - - /* Allocate room for absolute directory name and search pattern */ - dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); - if (dirp->patt) { - - /* - * Convert relative directory name to an absolute one. This - * allows rewinddir() to function correctly even when current - * working directory is changed between opendir() and rewinddir(). - */ - n = GetFullPathNameW (dirname, n, dirp->patt, NULL); - if (n > 0) { - wchar_t *p; - - /* Append search pattern \* to the directory name */ - p = dirp->patt + n; - if (dirp->patt < p) { - switch (p[-1]) { - case '\\': - case '/': - case ':': - /* Directory ends in path separator, e.g. c:\temp\ */ - /*NOP*/; - break; - - default: - /* Directory name doesn't end in path separator */ - *p++ = '\\'; - } - } - *p++ = '*'; - *p = '\0'; + if (!dirp) { + return NULL; + } - /* Open directory stream and retrieve the first entry */ - if (dirent_first (dirp)) { - /* Directory stream opened successfully */ - error = 0; - } else { - /* Cannot retrieve first entry */ - error = 1; - dirent_set_errno (ENOENT); - } + /* Reset _WDIR structure */ + dirp->handle = INVALID_HANDLE_VALUE; + dirp->patt = NULL; + dirp->cached = 0; + + /* + * Compute the length of full path plus zero terminator + * + * Note that on WinRT there's no way to convert relative paths + * into absolute paths, so just assume it is an absolute path. + */ +#if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_PHONE_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + /* WinRT */ + n = wcslen (dirname); +#else + /* Regular Windows */ + n = GetFullPathNameW (dirname, 0, NULL, NULL); +#endif - } else { - /* Cannot retrieve full path name */ - dirent_set_errno (ENOENT); - error = 1; - } + /* Allocate room for absolute directory name and search pattern */ + dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); + if (dirp->patt == NULL) { + goto exit_closedir; + } - } else { - /* Cannot allocate memory for search pattern */ - error = 1; - } + /* + * Convert relative directory name to an absolute one. This + * allows rewinddir() to function correctly even when current + * working directory is changed between opendir() and rewinddir(). + * + * Note that on WinRT there's no way to convert relative paths + * into absolute paths, so just assume it is an absolute path. + */ +#if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_PHONE_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + /* WinRT */ + wcsncpy_s (dirp->patt, n+1, dirname, n); +#else + /* Regular Windows */ + n = GetFullPathNameW (dirname, n, dirp->patt, NULL); + if (n <= 0) { + goto exit_closedir; + } +#endif - } else { - /* Cannot allocate _WDIR structure */ - error = 1; + /* Append search pattern \* to the directory name */ + p = dirp->patt + n; + switch (p[-1]) { + case '\\': + case '/': + case ':': + /* Directory ends in path separator, e.g. c:\temp\ */ + /*NOP*/; + break; + + default: + /* Directory name doesn't end in path separator */ + *p++ = '\\'; } + *p++ = '*'; + *p = '\0'; - /* Clean up in case of error */ - if (error && dirp) { - _wclosedir (dirp); - dirp = NULL; + /* Open directory stream and retrieve the first entry */ + if (!dirent_first (dirp)) { + goto exit_closedir; } + /* Success */ return dirp; + + /* Failure */ +exit_closedir: + _wclosedir (dirp); + return NULL; } /* - * Read next directory entry. The directory entry is returned in dirent - * structure in the d_name field. Individual directory entries returned by - * this function include regular files, sub-directories, pseudo-directories - * "." and ".." as well as volume labels, hidden files and system files. + * Read next directory entry. + * + * Returns pointer to static directory entry which may be overwritten by + * subsequent calls to _wreaddir(). */ static struct _wdirent* _wreaddir( _WDIR *dirp) { + struct _wdirent *entry; + + /* + * Read directory entry to buffer. We can safely ignore the return value + * as entry will be set to NULL in case of error. + */ + (void) _wreaddir_r (dirp, &dirp->ent, &entry); + + /* Return pointer to statically allocated directory entry */ + return entry; +} + +/* + * Read next directory entry. + * + * Returns zero on success. If end of directory stream is reached, then sets + * result to NULL and returns zero. + */ +static int +_wreaddir_r( + _WDIR *dirp, + struct _wdirent *entry, + struct _wdirent **result) +{ WIN32_FIND_DATAW *datap; - struct _wdirent *entp; /* Read next directory entry */ datap = dirent_next (dirp); @@ -384,46 +485,47 @@ _wreaddir( size_t n; DWORD attr; - /* Pointer to directory entry to return */ - entp = &dirp->ent; - /* * Copy file name as wide-character string. If the file name is too * long to fit in to the destination buffer, then truncate file name * to PATH_MAX characters and zero-terminate the buffer. */ n = 0; - while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) { - entp->d_name[n] = datap->cFileName[n]; + while (n < PATH_MAX && datap->cFileName[n] != 0) { + entry->d_name[n] = datap->cFileName[n]; n++; } - dirp->ent.d_name[n] = 0; + entry->d_name[n] = 0; /* Length of file name excluding zero terminator */ - entp->d_namlen = n; + entry->d_namlen = n; /* File type */ attr = datap->dwFileAttributes; if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { - entp->d_type = DT_CHR; + entry->d_type = DT_CHR; } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { - entp->d_type = DT_DIR; + entry->d_type = DT_DIR; } else { - entp->d_type = DT_REG; + entry->d_type = DT_REG; } /* Reset dummy fields */ - entp->d_ino = 0; - entp->d_reclen = sizeof (struct _wdirent); + entry->d_ino = 0; + entry->d_off = 0; + entry->d_reclen = sizeof (struct _wdirent); + + /* Set result address */ + *result = entry; } else { - /* Last directory entry read */ - entp = NULL; + /* Return NULL to indicate end of directory */ + *result = NULL; } - return entp; + return /*OK*/0; } /* @@ -441,23 +543,21 @@ _wclosedir( /* Release search handle */ if (dirp->handle != INVALID_HANDLE_VALUE) { FindClose (dirp->handle); - dirp->handle = INVALID_HANDLE_VALUE; } /* Release search pattern */ - if (dirp->patt) { - free (dirp->patt); - dirp->patt = NULL; - } + free (dirp->patt); /* Release directory structure */ free (dirp); ok = /*success*/0; } else { + /* Invalid directory stream */ dirent_set_errno (EBADF); ok = /*failure*/-1; + } return ok; } @@ -487,9 +587,12 @@ dirent_first( _WDIR *dirp) { WIN32_FIND_DATAW *datap; + DWORD error; /* Open directory and retrieve the first entry */ - dirp->handle = FindFirstFileW (dirp->patt, &dirp->data); + dirp->handle = FindFirstFileExW( + dirp->patt, FindExInfoStandard, &dirp->data, + FindExSearchNameMatch, NULL, 0); if (dirp->handle != INVALID_HANDLE_VALUE) { /* a directory entry is now waiting in memory */ @@ -498,15 +601,38 @@ dirent_first( } else { - /* Failed to re-open directory: no directory entry in memory */ + /* Failed to open directory: no directory entry in memory */ dirp->cached = 0; datap = NULL; + /* Set error code */ + error = GetLastError (); + switch (error) { + case ERROR_ACCESS_DENIED: + /* No read access to directory */ + dirent_set_errno (EACCES); + break; + + case ERROR_DIRECTORY: + /* Directory name is invalid */ + dirent_set_errno (ENOTDIR); + break; + + case ERROR_PATH_NOT_FOUND: + default: + /* Cannot find the file */ + dirent_set_errno (ENOENT); + } + } return datap; } -/* Get next directory entry (internal) */ +/* + * Get next directory entry (internal). + * + * Returns + */ static WIN32_FIND_DATAW* dirent_next( _WDIR *dirp) @@ -527,7 +653,7 @@ dirent_next( /* Got a file */ p = &dirp->data; } else { - /* The very last entry has been processed or an error occured */ + /* The very last entry has been processed or an error occurred */ FindClose (dirp->handle); dirp->handle = INVALID_HANDLE_VALUE; p = NULL; @@ -552,6 +678,8 @@ opendir( { struct DIR *dirp; int error; + wchar_t wname[PATH_MAX + 1]; + size_t n; /* Must have directory name */ if (dirname == NULL || dirname[0] == '\0') { @@ -561,67 +689,71 @@ opendir( /* Allocate memory for DIR structure */ dirp = (DIR*) malloc (sizeof (struct DIR)); - if (dirp) { - wchar_t wname[PATH_MAX]; - size_t n; - - /* Convert directory name to wide-character string */ - error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX); - if (!error) { - - /* Open directory stream using wide-character name */ - dirp->wdirp = _wopendir (wname); - if (dirp->wdirp) { - /* Directory stream opened */ - error = 0; - } else { - /* Failed to open directory stream */ - error = 1; - } - - } else { - /* - * Cannot convert file name to wide-character string. This - * occurs if the string contains invalid multi-byte sequences or - * the output buffer is too small to contain the resulting - * string. - */ - error = 1; - } + if (!dirp) { + return NULL; + } - } else { - /* Cannot allocate DIR structure */ - error = 1; + /* Convert directory name to wide-character string */ + error = dirent_mbstowcs_s( + &n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1); + if (error) { + /* + * Cannot convert file name to wide-character string. This + * occurs if the string contains invalid multi-byte sequences or + * the output buffer is too small to contain the resulting + * string. + */ + goto exit_free; } - /* Clean up in case of error */ - if (error && dirp) { - free (dirp); - dirp = NULL; + + /* Open directory stream using wide-character name */ + dirp->wdirp = _wopendir (wname); + if (!dirp->wdirp) { + goto exit_free; } + /* Success */ return dirp; + + /* Failure */ +exit_free: + free (dirp); + return NULL; } /* * Read next directory entry. - * - * When working with text consoles, please note that file names returned by - * readdir() are represented in the default ANSI code page while any output to - * console is typically formatted on another code page. Thus, non-ASCII - * characters in file names will not usually display correctly on console. The - * problem can be fixed in two ways: (1) change the character set of console - * to 1252 using chcp utility and use Lucida Console font, or (2) use - * _cprintf function when writing to console. The _cprinf() will re-encode - * ANSI strings to the console code page so many non-ASCII characters will - * display correcly. */ static struct dirent* readdir( DIR *dirp) { + struct dirent *entry; + + /* + * Read directory entry to buffer. We can safely ignore the return value + * as entry will be set to NULL in case of error. + */ + (void) readdir_r (dirp, &dirp->ent, &entry); + + /* Return pointer to statically allocated directory entry */ + return entry; +} + +/* + * Read next directory entry into called-allocated buffer. + * + * Returns zero on success. If the end of directory stream is reached, then + * sets result to NULL and returns zero. + */ +static int +readdir_r( + DIR *dirp, + struct dirent *entry, + struct dirent **result) +{ WIN32_FIND_DATAW *datap; - struct dirent *entp; /* Read next directory entry */ datap = dirent_next (dirp->wdirp); @@ -631,7 +763,7 @@ readdir( /* Attempt to convert file name to multi-byte string */ error = dirent_wcstombs_s( - &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX); + &n, entry->d_name, PATH_MAX + 1, datap->cFileName, PATH_MAX + 1); /* * If the file name cannot be represented by a multi-byte string, @@ -645,55 +777,60 @@ readdir( */ if (error && datap->cAlternateFileName[0] != '\0') { error = dirent_wcstombs_s( - &n, dirp->ent.d_name, PATH_MAX, - datap->cAlternateFileName, PATH_MAX); + &n, entry->d_name, PATH_MAX + 1, + datap->cAlternateFileName, PATH_MAX + 1); } if (!error) { DWORD attr; - /* Initialize directory entry for return */ - entp = &dirp->ent; - /* Length of file name excluding zero terminator */ - entp->d_namlen = n - 1; + entry->d_namlen = n - 1; /* File attributes */ attr = datap->dwFileAttributes; if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { - entp->d_type = DT_CHR; + entry->d_type = DT_CHR; } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { - entp->d_type = DT_DIR; + entry->d_type = DT_DIR; } else { - entp->d_type = DT_REG; + entry->d_type = DT_REG; } /* Reset dummy fields */ - entp->d_ino = 0; - entp->d_reclen = sizeof (struct dirent); + entry->d_ino = 0; + entry->d_off = 0; + entry->d_reclen = sizeof (struct dirent); } else { + /* * Cannot convert file name to multi-byte string so construct - * an errornous directory entry and return that. Note that + * an erroneous directory entry and return that. Note that * we cannot return NULL as that would stop the processing * of directory entries completely. */ - entp = &dirp->ent; - entp->d_name[0] = '?'; - entp->d_name[1] = '\0'; - entp->d_namlen = 1; - entp->d_type = DT_UNKNOWN; - entp->d_ino = 0; - entp->d_reclen = 0; + entry->d_name[0] = '?'; + entry->d_name[1] = '\0'; + entry->d_namlen = 1; + entry->d_type = DT_UNKNOWN; + entry->d_ino = 0; + entry->d_off = -1; + entry->d_reclen = 0; + } + /* Return pointer to directory entry */ + *result = entry; + } else { + /* No more directory entries */ - entp = NULL; + *result = NULL; + } - return entp; + return /*OK*/0; } /* @@ -734,6 +871,162 @@ rewinddir( _wrewinddir (dirp->wdirp); } +/* + * Scan directory for entries. + */ +static int +scandir( + const char *dirname, + struct dirent ***namelist, + int (*filter)(const struct dirent*), + int (*compare)(const struct dirent**, const struct dirent**)) +{ + struct dirent **files = NULL; + size_t size = 0; + size_t allocated = 0; + const size_t init_size = 1; + DIR *dir = NULL; + struct dirent *entry; + struct dirent *tmp = NULL; + size_t i; + int result = 0; + + /* Open directory stream */ + dir = opendir (dirname); + if (dir) { + + /* Read directory entries to memory */ + while (1) { + + /* Enlarge pointer table to make room for another pointer */ + if (size >= allocated) { + void *p; + size_t num_entries; + + /* Compute number of entries in the enlarged pointer table */ + if (size < init_size) { + /* Allocate initial pointer table */ + num_entries = init_size; + } else { + /* Double the size */ + num_entries = size * 2; + } + + /* Allocate first pointer table or enlarge existing table */ + p = realloc (files, sizeof (void*) * num_entries); + if (p != NULL) { + /* Got the memory */ + files = (dirent**) p; + allocated = num_entries; + } else { + /* Out of memory */ + result = -1; + break; + } + + } + + /* Allocate room for temporary directory entry */ + if (tmp == NULL) { + tmp = (struct dirent*) malloc (sizeof (struct dirent)); + if (tmp == NULL) { + /* Cannot allocate temporary directory entry */ + result = -1; + break; + } + } + + /* Read directory entry to temporary area */ + if (readdir_r (dir, tmp, &entry) == /*OK*/0) { + + /* Did we get an entry? */ + if (entry != NULL) { + int pass; + + /* Determine whether to include the entry in result */ + if (filter) { + /* Let the filter function decide */ + pass = filter (tmp); + } else { + /* No filter function, include everything */ + pass = 1; + } + + if (pass) { + /* Store the temporary entry to pointer table */ + files[size++] = tmp; + tmp = NULL; + + /* Keep up with the number of files */ + result++; + } + + } else { + + /* + * End of directory stream reached => sort entries and + * exit. + */ + qsort (files, size, sizeof (void*), + (int (*) (const void*, const void*)) compare); + break; + + } + + } else { + /* Error reading directory entry */ + result = /*Error*/ -1; + break; + } + + } + + } else { + /* Cannot open directory */ + result = /*Error*/ -1; + } + + /* Release temporary directory entry */ + free (tmp); + + /* Release allocated memory on error */ + if (result < 0) { + for (i = 0; i < size; i++) { + free (files[i]); + } + free (files); + files = NULL; + } + + /* Close directory stream */ + if (dir) { + closedir (dir); + } + + /* Pass pointer table to caller */ + if (namelist) { + *namelist = files; + } + return result; +} + +/* Alphabetical sorting */ +static int +alphasort( + const struct dirent **a, const struct dirent **b) +{ + return strcoll ((*a)->d_name, (*b)->d_name); +} + +/* Sort versions */ +static int +versionsort( + const struct dirent **a, const struct dirent **b) +{ + /* FIXME: implement strverscmp and use that */ + return alphasort (a, b); +} + /* Convert multi-byte string to wide character string */ static int dirent_mbstowcs_s( @@ -744,46 +1037,87 @@ dirent_mbstowcs_s( size_t count) { int error; - -#if defined(_MSC_VER) && _MSC_VER >= 1400 - - /* Microsoft Visual Studio 2005 or later */ - error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count); - + int n; + size_t len; + UINT cp; + DWORD flags; + + /* Determine code page for multi-byte string */ +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + if (AreFileApisANSI ()) { + /* Default ANSI code page */ + cp = GetACP (); + } else { + /* Default OEM code page */ + cp = GetOEMCP (); + } #else + cp = CP_ACP; +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + + /* + * Determine flags based on the character set. For more information, + * please see https://docs.microsoft.com/fi-fi/windows/desktop/api/stringapiset/nf-stringapiset-multibytetowidechar + */ + switch (cp) { + case 42: + case 50220: + case 50221: + case 50222: + case 50225: + case 50227: + case 50229: + case 57002: + case 57003: + case 57004: + case 57005: + case 57006: + case 57007: + case 57008: + case 57009: + case 57010: + case 57011: + case 65000: + /* MultiByteToWideChar does not support MB_ERR_INVALID_CHARS */ + flags = 0; + break; + + default: + /* + * Ask MultiByteToWideChar to return an error if a multi-byte + * character cannot be converted to a wide-character. + */ + flags = MB_ERR_INVALID_CHARS; + } - /* Older Visual Studio or non-Microsoft compiler */ - size_t n; + /* Compute the length of input string without zero-terminator */ + len = 0; + while (mbstr[len] != '\0' && len < count) { + len++; + } - /* Convert to wide-character string (or count characters) */ - n = mbstowcs (wcstr, mbstr, sizeInWords); - if (!wcstr || n < count) { + /* Convert to wide-character string */ + n = MultiByteToWideChar( + /* Source code page */ cp, + /* Flags */ flags, + /* Pointer to string to convert */ mbstr, + /* Size of multi-byte string */ (int) len, + /* Pointer to output buffer */ wcstr, + /* Size of output buffer */ (int)sizeInWords - 1 + ); - /* Zero-terminate output buffer */ - if (wcstr && sizeInWords) { - if (n >= sizeInWords) { - n = sizeInWords - 1; - } - wcstr[n] = 0; - } + /* Ensure that output buffer is zero-terminated */ + wcstr[n] = '\0'; - /* Length of resuting multi-byte string WITH zero terminator */ - if (pReturnValue) { - *pReturnValue = n + 1; - } + /* Return length of wide-character string with zero-terminator */ + *pReturnValue = (size_t) (n + 1); - /* Success */ + /* Return zero if conversion succeeded */ + if (n > 0) { error = 0; - } else { - - /* Could not convert string */ error = 1; - } - -#endif - return error; } @@ -796,47 +1130,82 @@ dirent_wcstombs_s( const wchar_t *wcstr, size_t count) { + int n; int error; - -#if defined(_MSC_VER) && _MSC_VER >= 1400 - - /* Microsoft Visual Studio 2005 or later */ - error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count); - + UINT cp; + size_t len; + BOOL flag = 0; + LPBOOL pflag; + + /* Determine code page for multi-byte string */ +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + if (AreFileApisANSI ()) { + /* Default ANSI code page */ + cp = GetACP (); + } else { + /* Default OEM code page */ + cp = GetOEMCP (); + } #else + cp = CP_ACP; +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) - /* Older Visual Studio or non-Microsoft compiler */ - size_t n; - /* Convert to multi-byte string (or count the number of bytes needed) */ - n = wcstombs (mbstr, wcstr, sizeInBytes); - if (!mbstr || n < count) { + /* Compute the length of input string without zero-terminator */ + len = 0; + while (wcstr[len] != '\0' && len < count) { + len++; + } - /* Zero-terminate output buffer */ - if (mbstr && sizeInBytes) { - if (n >= sizeInBytes) { - n = sizeInBytes - 1; - } - mbstr[n] = '\0'; - } + /* + * Determine if we can ask WideCharToMultiByte to return information on + * broken characters. For more information, please see + * https://docs.microsoft.com/en-us/windows/desktop/api/stringapiset/nf-stringapiset-widechartomultibyte + */ + switch (cp) { + case CP_UTF7: + case CP_UTF8: + /* + * WideCharToMultiByte fails if we request information on default + * characters. This is just a nuisance but doesn't affect the + * conversion: if Windows is configured to use UTF-8, then the default + * character should not be needed anyway. + */ + pflag = NULL; + break; - /* Lenght of resulting multi-bytes string WITH zero-terminator */ - if (pReturnValue) { - *pReturnValue = n + 1; - } + default: + /* + * Request that WideCharToMultiByte sets the flag if it uses the + * default character. + */ + pflag = &flag; + } - /* Success */ + /* Convert wide-character string to multi-byte character string */ + n = WideCharToMultiByte( + /* Target code page */ cp, + /* Flags */ 0, + /* Pointer to unicode string */ wcstr, + /* Length of unicode string */ (int) len, + /* Pointer to output buffer */ mbstr, + /* Size of output buffer */ (int)sizeInBytes - 1, + /* Default character */ NULL, + /* Whether default character was used or not */ pflag + ); + + /* Ensure that output buffer is zero-terminated */ + mbstr[n] = '\0'; + + /* Return length of multi-byte string with zero-terminator */ + *pReturnValue = (size_t) (n + 1); + + /* Return zero if conversion succeeded without using default characters */ + if (n > 0 && flag == 0) { error = 0; - } else { - - /* Cannot convert string */ error = 1; - } - -#endif - return error; } @@ -858,6 +1227,7 @@ dirent_set_errno( #endif } + #ifdef __cplusplus } #endif |